Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution
On Nov 11, 2017, at 6:52 PM, Matthew Johnson  wrote:
 In point of fact, Swift already has the feature you are referring to.  It 
 just spells it with square brackets instead of parentheses.  A simple 
 change to the punctuation character has much less point than the proposal 
 that I’m pitching.
>>> 
>>> This is true if you squint, but I imagine a design for callable types would 
>>> include some 
>>>  differences other than just punctuation.
> 
> I think there was a pretty good discussion of this distinction in the  
> SE-0021 timeframe.  Specifically, subscripts model storage while callable 
> would model functions.  This means that subscripts can be used in a key path 
> while callable would not (at last for now).  

Sure, subscript getters are more general than calls in that respect, I agree.

> On the other hand, I would want to see callables implicitly convert to a 
> value of a compatible function type (possibly through a subtype relationship).

Subscripts are generalizations of the property model in Swift.  We’ve discussed 
being able to curry the getter of a property, so I don’t see why currying the 
getter of a subscript should work any different.  This would directly provide 
the functionality you’re referring to.

> Without this capability the syntactic illusion is only half complete.  The 
> callable feels like a function when used directly but not when it is assigned 
> to a function type or passed elsewhere - it must be explicitly be wrapped in 
> a closure and the arguments forwarded.  First-class callable types are a 
> syntactic sugar feature and as such if they exist they should be usable 
> syntactically in all of the same ways functions are.
> 
> Read-only subscripts are ok as a workaround in absence of first-class 
> callable types (although I think in many ways just using `call` is better).  
> Nevertheless, they are a workaround and can never be more than that because 
> of the fundamental difference in what they model.

Please don’t misunderstand me.  I’m not saying that:

let a = x[foo: 42, “bonk”, bar: 17]

is “better” than:

let a = x(foo: 42, “bonk”, bar: 17)

when x is a functor or something else function like.  Syntax matters: it is the 
principle way that language communicates to programmers, and sending an 
indexing connotation is very different than sending a call connotation.  My 
point is simply that we already have the ability to *express* this concept, so 
users have a way to solve a problem (even in a suboptimal way).  

In contrast, we do not have a way to express the dynamically callable form, 
which is the subject of my proposal.  The workaround is not a change of one 
punctuation character to another, it is a significantly heavier syntactic form 
like x.call(…) or perhaps Joe’s proposal of introducing weird punctuation.

In any case, as I have reiterated many times, I simply want to solve the Python 
import problem.  I am not wed to this approach.  If there is another approach 
that provides a equal (or better) result, then I’m super interested to hear 
about it.  The only alternative that I’m aware of is to burn support for Python 
into the Swift compiler, which I’m pretty opposed to doing: not only is it 
significantly more complexity than the proposals required to implement this in 
libraries, it also signs us up to do the same for Perl, Ruby, Javascript, …...

-Chris

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution
On Nov 11, 2017, at 6:24 PM, Joe Groff  wrote:
>> In contrast, it does *not* seem like it would help with the problem of 
>> resolving members of “id” typed values in Objective-C, which is the crux of 
>> the dynamic language problem.  If my understanding is correct, type 
>> providers seem completely unhelpful for python interoperability, because you 
>> don’t know the types of python values: anything loaded from a Python 
>> property or returned by a Python function is the equivalent of “id”.
>> 
>> It’s entirely possible I’m missing something big.  If so, I’d appreciate a 
>> pointer to something to read that explains how this works.  Thanks!
> 
> A type provider should let you provide custom logic for something the 
> compiler sees as a module, which can answer name lookup queries by producing 
> decls based on externally-available information.

Right.

> While Python is dynamic, Python culture doesn't go as wild with dynamic 
> shenanigans as other languages do;

I’m not sure what you mean by this, but it is not my experience that Python 
programs are widely monomorphic.  In fact, several Python API design experts I 
respect have mentioned that a natural effect of dynamic languages is “interface 
creep” where APIs end up accepting broader and broader sets of stuff to make 
them “just work” in more cases.

Static languages solve this heads on by allowing API authors to express their 
requirements.  I prefer this approach of course, but we’re talking about a real 
existing world here, not my preference :-)

> there are established idioms for communicating some level of type information 
> in doc comments (or more recently with first class syntax in Python 3),

Yes, Python 3 does have optional type annotations.  I’m not sure how widely 
used they are though, and given that the Python 2 community is (far?) larger 
than Python 3, this isn’t something we can depend on IMO.

> and people like code completion to work with their Python text editors, so 
> there's incentive to use them. A type provider in Swift could address not 
> only the syntax gap but the tooling gap from directly writing Python, since 
> it could answer name lookup requests into an imported Python type by static 
> analysis, and it could bring that declaration into Swift with doc comments 
> and other metadata intact. This would let Python decls get wired up to 
> Swift's code completion, quick help, and other IDE tooling.

Absolutely, I can see how type providers would provide nice refinement on top 
of basic “anyobject” style dispatch.  We still need to solve the basic problem 
though before providing refinements.

I’m also extremely concerned about how type providers work in practice.  With 
the disclaimer that I barely understand what is going on, it seems like they 
cause an extreme amount of compile-time work.  Implementing them seems to 
require implementing an interpreter into the compiler.  This is extremely 
concerning to me: for the same amount of complexity, we could burn many 
languages worth of special cases into Swift.

Since you’re apparently familiar with F#, are you aware of any efforts to use 
F# type providers to interoperate with dynamic languages?  How well does that 
actually work in practice?

> Since statically-available type info still isn't going to be perfect in 
> Python, and we don't want to be boxed in to type-annotated APIs, a type 
> provider could be lax with its name lookup behavior and allow any known 
> Python method to be found on any Python type, much like AnyObject's behavior 
> for ObjC methods (and, like AnyObject, maybe tag them with IUO types so that 
> type safety aficionados can test for their presence, and prioritizing the 
> "good" type-matching methods in code completion results). 

Right, but there is a very simple and closed problem to solve here.  Type 
providers don’t solve it, and so now you’re basically saying that type 
providers could be extended to provide exactly the same functionality I’m 
describing, but in a far more opaque, difficult to use, and significantly more 
compile time intensive approach.

Type providers may be a cool thing in principle, but if you’re going to 
advocate for them, I think we should start with a discussion about whether they 
would ever be realistically implemented in Swift (ignoring schedule).  Further, 
whatever extension you’re imagining to solve the “anyobject dispatch” problem 
will require making Swift types “Callable" anyways (so the type provider can 
provide that type).  

At that point, I would ask why type providers are in the critical path.  It 
seems obvious to implement the underlying type that the providers would provide 
first.  It’s not like we said we should wait to introduce structs until type 
providers exist.

-Chris



___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Nov 11, 2017, at 5:27 PM, Chris Lattner  wrote:
> 
> Ok, which differences?
> 
> -Chris
> 
>> On Nov 11, 2017, at 2:19 PM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> 
>> 
>> Sent from my iPad
>> 
>>> On Nov 11, 2017, at 11:40 AM, Chris Lattner  wrote:
>>> 
>>> On Nov 10, 2017, at 6:10 PM, Matthew Johnson via swift-evolution 
>>>  wrote:
>> On Nov 10, 2017, at 11:25 AM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
 
 People have reasonably asked for the ability to make their own 
 function-like types in the past, such that "myvalue(...)" behaves like 
 sugar for "myvalue.call(...)" or something like that. In most cases, 
 they still want to have type system control over what arguments and 
 results their call operation produces. They don't really get that with 
 this proposal; they lose all control over the arity and argument 
 types. 
>>> 
>>> As I mentioned, this is directly addressed in the writeup. Here’s the 
>>> link:
>>> https://gist.github.com/lattner/a6257f425f55fe39fd6ac7a2354d693d#staticly-checking-for-exact-signatures
>> 
>> That discusses why you didn’t include it in the present proposal but I 
>> think it’s reasonable to oppose adding a dynamic callable feature prior 
>> to a more Swifty static callable.
> 
> Why?  One does not preclude the other.
 
 For exactly the reason Joe articulates.  Some people will use what the 
 language offers to get the syntax they desire even if it sacrifices type 
 safety.  If we’re going to have first-class callable types in Swift (I 
 think it’s a great idea) type safety for native code should be prioritized 
 over syntactic convenience for dynamic language interop.  We can have 
 both, but the former should come first IMO.
>>> 
>>> Hi Matthew,
>>> 
>>> In point of fact, Swift already has the feature you are referring to.  It 
>>> just spells it with square brackets instead of parentheses.  A simple 
>>> change to the punctuation character has much less point than the proposal 
>>> that I’m pitching.
>> 
>> This is true if you squint, but I imagine a design for callable types would 
>> include some 
>>  differences other than just punctuation.

I think there was a pretty good discussion of this distinction in the  SE-0021 
timeframe.  Specifically, subscripts model storage while callable would model 
functions.  This means that subscripts can be used in a key path while callable 
would not (at last for now).  

On the other hand, I would want to see callables implicitly convert to a value 
of a compatible function type (possibly through a subtype relationship). 
Without this capability the syntactic illusion is only half complete.  The 
callable feels like a function when used directly but not when it is assigned 
to a function type or passed elsewhere - it must be explicitly be wrapped in a 
closure and the arguments forwarded.  First-class callable types are a 
syntactic sugar feature and as such if they exist they should be usable 
syntactically in all of the same ways functions are.

Read-only subscripts are ok as a workaround in absence of first-class callable 
types (although I think in many ways just using `call` is better).  
Nevertheless, they are a workaround and can never be more than that because of 
the fundamental difference in what they model.

Matthew

>> 
>>> 
>>> -Chris
>>> 
>>> 
>> ___
>> 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


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Andrew Bennett via swift-evolution
Thanks for taking the time to respond. I think my confusion started from a
misinterpretation that each method you're exposing from python would need a
new implementation of the protocol. I've worked out my mistake, and you
helped clarified with:

> The system I’ve sketched out does not incorporate Python declarations,
everything is dynamic

You've addressed the other things that didn't stem from that :)

Thanks,
Andrew

On Sun, Nov 12, 2017 at 12:27 PM, Chris Lattner  wrote:

> On Nov 11, 2017, at 4:15 PM, Andrew Bennett  wrote:
>
> HI, this proposal looks really interesting!
>
>
> Thanks!
>
> *Clarity on the proposal's intent*
> *Nice cheap bridges, or lowering barriers to bridging?*
>
>
> The later: I’m not overly concerned about constant time performance:
> dynamic languages are often slow (though exceptions exist, e.g.
> Javascript).  So if there is a beautiful approach that works great but is a
> bit slower, that is fine with me.
>
> My desire is to enable access to “any” API in Python directly from Swift
> with natural syntax.  This doesn’t mean it has to match Python of course:
> Python ranges and Swift ranges are syntactically very different, and
> Swift-in-Python should use Swift syntax.  That said, there are a LOT of
> expression level similarities between Swift and Python, so things that can
> be the same should be.
>
> This proposal isn’t the only way to achieve that, of course.  I’m open to
> other suggestions.
>
> I can see this providing a nice quick interface to Python from Swift, but
> I'm not sure if the exposed interface will be very Swifty (you probably
> have a much better idea of what is Swifty ;) than I do though). It seems
> you want it to be possible for everything to be dynamically exposed
>
>
> Right: Python APIs are not “Swifty”.  They do not use optionals or
> generics, use lowercase snake names, etc.  IMO, that’s perfectly fine.
> Unlike the Objective-C interop in Swift - which aims to make legacy ObjC
> APIs feel Swifty, it is perfectly acceptable (and far less impact on the
> compiler) to just import Python directly into Swift.  This is actually much
> better for the target audience anyway.
>
> Is it common for the the argument labels in other languages to be open
> ended, or are labels typically finite? If the answer is finite, why not use
> a Swift method as the wrapper?
>
>
> Python keyword arguments are open ended.  They get passed to the Python
> API as a dictionary.
>
> Do you want duck typing, and would it be better to expose this via a
> protocol?
>
>
> I’m not sure how that can work, can you elaborate?
>
> It seems like in almost every case you could do something like this:
>
> func myMethod(a: X?
> = nil, b: Y) {
> pythonBridge.call("myMethod", arguments: ["a": X, "b": Y])
> }
>
>
> The currency type is PyVal (name TBD of course), just like AnyObject for
> Objective-C. I’m not sure what the code above is getting at.
>
> It might be good to add some *use-cases* (a popular Python library
> perhaps) to the proposal where this type of bridge would be insufficient :).
>
>
> There are lots of examples.  In data science, NumPy and Pandas are two
> examples.  The Python community is 1 or 2 orders of magnitude larger than
> Swift’s community and there is 25 years of code out there to interop with.
> The point of this is to make it all accessible.
>
> It seems like this proposal pushes the responsibility of Swifty-ness and
> type-safety to the caller.
>
>
> Yes, welcome to dynamic languages :-)
>
> At some point you'll have to write a type-safe bridging layer, or write
> your entire program in non-Swifty code ("The most obvious way to write code
> should also behave in a safe manner"). Is the main goal to *lower the
> barrier to Python* and other dynamic languages? or is it to provide a
> cheap nice Swifty bridge? I have the above concerns about the latter.
>
>
> It’s the later.  Many Python APIs are already wrappers around C code, so
> if someone cares about investing a bunch of effort into making a great
> Swift API, it would generally make sense to wrap the C API in Swift, not
> wrap the Python API in Swift.
>
> *Alternative sugar*
>
> Ruby has Keyword Arguments for similar sugar:
>
> *def* foo(regular, hash={})
> *puts* "the hash: #{hash}"
>
>
> I'm sure you're aware of it, but I'll explain for completeness, any
> trailing argument labels are stored and passed as a hash:
>
> foo(regular, bar: "hello", bas: 123) *# outputs 'the hash: [**bar: "hello", 
> bas: 123]’*
>
> Python is similar, but allows them to be intermixed with positional
> arguments.
>
> Have you considered an alternative like this? For example:
>
> func myMethod(regular: Int, store: @argcapture [String: PythonConvertible])
> -> PythonConvertible
>
> I'm sure you have good reasons, it might make the implementation bleed out
> into other parts of the codebase. It would be good to include it in the
> proposal *alternatives* section though. At the moment most of the

Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Joe Groff via swift-evolution


> On Nov 11, 2017, at 1:57 PM, Chris Lattner  wrote:
> 
> 
> 
>>> On Nov 11, 2017, at 10:17 AM, Chris Lattner via swift-evolution 
>>>  wrote:
>>> 
>>> so I don't think there's a time constraint forcing us to consider the 
>>> "narrow" vs "huge" dimension. What's the best thing for the language and 
>>> tools in the long term? This is a feature that influences the semantics of 
>>> potentially any call site in all Swift code, which we'd have to live with 
>>> forever if we accepted it now. Opening up the compiler architecture to make 
>>> custom importers easier to write is a great solution to a ton of problems, 
>>> including yours I think, without adding complexity to the core language. 
>>> Experience in .NET land seems to show it's a great technique for 
>>> integrating dynamic systems with static type systems, without poking 
>>> unnecessary holes in the static language's type system
>> 
>> As I mentioned, I’m not familiar with F# type providers.  As I told you 
>> upthread, I will read about them and respond with an informed opinion when I 
>> have time.
> 
> I have done some quick reading about type providers, but I am certainly not 
> an expert.  I have a couple of questions that I’d appreciate your insight on:
> 
> Type providers seem like a (complicated!) compile-time form of meta 
> programming or compiler plugin.  How does this help interoperability with 
> dynamic languages, where the preponderance of values have types that are not 
> knowable at compile time?
> 
> To pick a specific example you are familiar with, this seems like it could 
> help in theory (though I suspect it would be be entirely impractical in 
> practice) to provide types for Objective-C methods that are coming from an 
> SDK where you have declarations.  
> 
> In contrast, it does *not* seem like it would help with the problem of 
> resolving members of “id” typed values in Objective-C, which is the crux of 
> the dynamic language problem.  If my understanding is correct, type providers 
> seem completely unhelpful for python interoperability, because you don’t know 
> the types of python values: anything loaded from a Python property or 
> returned by a Python function is the equivalent of “id”.
> 
> It’s entirely possible I’m missing something big.  If so, I’d appreciate a 
> pointer to something to read that explains how this works.  Thanks!

A type provider should let you provide custom logic for something the compiler 
sees as a module, which can answer name lookup queries by producing decls based 
on externally-available information. While Python is dynamic, Python culture 
doesn't go as wild with dynamic shenanigans as other languages do; there are 
established idioms for communicating some level of type information in doc 
comments (or more recently with first class syntax in Python 3), and people 
like code completion to work with their Python text editors, so there's 
incentive to use them. A type provider in Swift could address not only the 
syntax gap but the tooling gap from directly writing Python, since it could 
answer name lookup requests into an imported Python type by static analysis, 
and it could bring that declaration into Swift with doc comments and other 
metadata intact. This would let Python decls get wired up to Swift's code 
completion, quick help, and other IDE tooling.

Since statically-available type info still isn't going to be perfect in Python, 
and we don't want to be boxed in to type-annotated APIs, a type provider could 
be lax with its name lookup behavior and allow any known Python method to be 
found on any Python type, much like AnyObject's behavior for ObjC methods (and, 
like AnyObject, maybe tag them with IUO types so that type safety aficionados 
can test for their presence, and prioritizing the "good" type-matching methods 
in code completion results). I don't think that's a totally silly idea; much 
like AnyObject lookup is strictly an ObjC interop feature, I think there'd be 
benefit to keeping lax name lookup behavior a Python interop facilitator rather 
than a general language feature.

-Joe___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] JSONEncoder: Key strategies

2017-11-11 Thread Mike Kluev via swift-evolution
On 11 November 2017 at 21:56, Eagle Offshore  wrote:

> I have to agree, would be better to allow one to provide a mapping
> dictionary or delegate.  Building the encodingKeys into the class itself is
> short sighted and a half measure.
>
> Different types of codings will necessarily desire different key sets and
> even different names for what are logically the same keys.  This absolutely
> should NOT be baked into the class that implements Codable but rather maybe
> a delegate that is presented each key/value and given an opportunity to
> provide a substitute key and value.
>
> Codable is a fairly useless one trick pony in its current incarnation.  It
> doesn't really solve any problem I have with respect to interacting with
> web services.
>
>

in defence of Codable, my experience so far told me:

- it is very useful

- easy to use especially when you can change those structures / keys, e.g.
when you have an influence on the service side as well, or the service side
is designed at the same time - when you start from clean state in other
words.

- even if you need to talk to an already established service - the key's
translation it's doable now (could have been easier though)

- it is very logical to hook the logic of the key translation in the
Codable subclass itself (maybe in a different form to what it is now)
rather than do it externally - the latter is a more "manual" and thus a
more error prone approach where things can be easily screwed.

- the ideal design (not current) would allow to do the translation the way
you want (e.g. via the delegate). so shall be win-win.

Mike
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Re-pitch: Deriving collections of enum cases

2017-11-11 Thread Andrew Bennett via swift-evolution
On Mon, Nov 6, 2017 at 6:54 PM, Jacob Bandes-Storch via swift-evolution <
swift-evolution@swift.org> wrote:

> Over a year ago, we discussed adding a magic "allValues"/"allCases" static
> property on enums with a compiler-derived implementation. The original 
> proposal
> PR  has been reopened
> for Swift 5 after languishing for a while, and I'd like to revisit it and
> make some changes before it goes up for formal review.
>
> Prior discussion: https://lists.swift.org/pipermail/swift-
> evolution/Week-of-Mon-20160411/015098.html (good luck finding the rest of
> the thread if you weren't on the list at the time...)
>
> [cc'd swift-dev for importer/availability-related topics below.]
>
> ***Naming***
>
> Given the complexity gap between a simple enumeration of cases and full
> support for non-enum types and associated values (which we don't intend to
> support with this proposal), I think it might be a good idea to adopt the
> names *CaseEnumerable/allCases* instead of ValueEnumerable/allValues.
>
> The original proposal didn't expose allValues as a requirement, for fear
> of unduly restricting its type. However, if the protocol's scope is more
> limited, *static var allCases* can be exposed as a requirement since the
> implementations are not likely to be complex. Furthermore...
>
>
> ***Generics***
>
> Since SE-0142
> 
> was implemented in Swift 4, we now have more expressive options for the
> protocol requirements:
>
>   // 1 - array only
>   protocol CaseEnumerable {
> static var allCases: [Self] { get }
>   }
>
>   // 2 - any sequence
>   protocol CaseEnumerable {
> associatedtype *CaseSequence*: Sequence where CaseSequence.Element ==
> Self
> static var *allCases*: CaseSequence { get }
>   }
>
>   // 3 - any collection
>   protocol CaseEnumerable {
> associatedtype *CaseCollection*: Collection where
> CaseCollection.Element == Self
> static var *allCases*: CaseCollection { get }
>   }
>
> This restricts the CaseEnumerable protocol to be used as a generic
> constraint, but that'd be true even with a plain array because of the Self
> type.
>
> Personally I like the flexibility provided by the associatedtype, but I
> also recognize it won't be incredibly useful for enums — more so if we
> wanted to provide e.g. UInt8.allValues, whose ideal implementation might be
> "return 0...UInt8.max". So I could see allowing allValues to be any
> sequence or collection, but flexibility for allCases might be less
> important. Others should weigh in here.
>
>
> ***Implementation strategy and edge cases***
>
> Last year , Robert
> Widmann put together an implementation of CaseEnumerable: https://
> github.com/apple/swift/compare/master...CodaFi:ace-attorney
> I'd love to hear from anyone more familiar with the code whether there's
> anything we'd want to change about this approach.
>
> A few tricky situations have been brought to my attention:
>
> - Enums *imported from C/Obj-C* headers. Doug Gregor writes: *"The
> autogenerated allValues would only be able to list the enum cases it knows
> about from the header it was compiled with. If the library changes to
> add cases in the future (which, for example, Apple frameworks tend to do),
> those wouldn’t be captured in allValues."*
>
>
This proposal would be very useful in reducing boiler plate code in many
cases!

With "Enums imported from C/Obj-C headers", it would be nice to
automatically bridge it by using an appropriately namespaced (and
dynamically loaded) ObjC equivalent values(s), if one is available. I think
this addresses Doug's concerns.

For example:

//

// Foundation NSObjCRuntime.h

//

#define NS_VALUE_ENUMERABLE(__TYPE__) \

FOUNDATION_EXPORT NSInteger const __TYPE__ ##ValueCount; \

FOUNDATION_EXPORT __TYPE__ __TYPE__##ValueAtIndex(NSInteger index);


//

// UITableViewCellStyle.h

//


...


NS_VALUE_ENUMERABLE(UITableViewCellStyle);

//

// UITableViewCellStyle.m

//

...

NSInteger const  UITableViewCellStyleValueCount = 4;

UITableViewCellStyle UITableViewCellStyleValueAtIndex(NSInteger index) {

// Can be a switch statement in more complicated cases

return (UITableViewCellStyle) index;

}


//

// UITableViewCellStyle-Generated.swift

//


extension UITableViewCellStyle: ValueEnumerable {

typealias AllValuesCollection = _NSValueEnumerableCollection<
UITableViewCellStyle>

static var allValues: AllValuesCollection {

return AllValuesCollection(

count: UITableViewCellStyleValueCount,

valueAtIndex: UITableViewCellStyleValueAtIndex)

}

}

//

// Swift Standard Library

//

public struct _NSValueEnumerableCollection: Collection {

private let valueAtIndex: (Int) -> T

public let count: Int

public var startIndex: Int { return 0 }

public var 

Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution
On Nov 11, 2017, at 4:15 PM, Andrew Bennett  wrote:
> HI, this proposal looks really interesting!

Thanks!

> Clarity on the proposal's intent
> Nice cheap bridges, or lowering barriers to bridging?

The later: I’m not overly concerned about constant time performance: dynamic 
languages are often slow (though exceptions exist, e.g. Javascript).  So if 
there is a beautiful approach that works great but is a bit slower, that is 
fine with me.

My desire is to enable access to “any” API in Python directly from Swift with 
natural syntax.  This doesn’t mean it has to match Python of course: Python 
ranges and Swift ranges are syntactically very different, and Swift-in-Python 
should use Swift syntax.  That said, there are a LOT of expression level 
similarities between Swift and Python, so things that can be the same should be.

This proposal isn’t the only way to achieve that, of course.  I’m open to other 
suggestions.

> I can see this providing a nice quick interface to Python from Swift, but I'm 
> not sure if the exposed interface will be very Swifty (you probably have a 
> much better idea of what is Swifty ;) than I do though). It seems you want it 
> to be possible for everything to be dynamically exposed


Right: Python APIs are not “Swifty”.  They do not use optionals or generics, 
use lowercase snake names, etc.  IMO, that’s perfectly fine.  Unlike the 
Objective-C interop in Swift - which aims to make legacy ObjC APIs feel Swifty, 
it is perfectly acceptable (and far less impact on the compiler) to just import 
Python directly into Swift.  This is actually much better for the target 
audience anyway.

> Is it common for the the argument labels in other languages to be open ended, 
> or are labels typically finite? If the answer is finite, why not use a Swift 
> method as the wrapper?

Python keyword arguments are open ended.  They get passed to the Python API as 
a dictionary.

> Do you want duck typing, and would it be better to expose this via a protocol?

I’m not sure how that can work, can you elaborate?

> It seems like in almost every case you could do something like this:
> 
> func myMethod(a: X? = 
> nil, b: Y) {
> pythonBridge.call("myMethod", arguments: ["a": X, "b": Y])
> }

The currency type is PyVal (name TBD of course), just like AnyObject for 
Objective-C. I’m not sure what the code above is getting at.

> It might be good to add some use-cases (a popular Python library perhaps) to 
> the proposal where this type of bridge would be insufficient :).

There are lots of examples.  In data science, NumPy and Pandas are two 
examples.  The Python community is 1 or 2 orders of magnitude larger than 
Swift’s community and there is 25 years of code out there to interop with.  The 
point of this is to make it all accessible.

> It seems like this proposal pushes the responsibility of Swifty-ness and 
> type-safety to the caller.

Yes, welcome to dynamic languages :-)

> At some point you'll have to write a type-safe bridging layer, or write your 
> entire program in non-Swifty code ("The most obvious way to write code should 
> also behave in a safe manner"). Is the main goal to lower the barrier to 
> Python and other dynamic languages? or is it to provide a cheap nice Swifty 
> bridge? I have the above concerns about the latter.

It’s the later.  Many Python APIs are already wrappers around C code, so if 
someone cares about investing a bunch of effort into making a great Swift API, 
it would generally make sense to wrap the C API in Swift, not wrap the Python 
API in Swift.

> Alternative sugar
> 
> Ruby has Keyword Arguments for similar sugar:
> 
> def foo(regular, hash={})
> puts "the hash: #{hash}"
> 
> 
> I'm sure you're aware of it, but I'll explain for completeness, any trailing 
> argument labels are stored and passed as a hash:
> 
> foo(regular, bar: "hello", bas: 123) # outputs 'the hash: [bar: "hello", bas: 
> 123]’
Python is similar, but allows them to be intermixed with positional arguments.

> Have you considered an alternative like this? For example:
> 
> func myMethod(regular: Int, store: @argcapture [String: PythonConvertible]) 
> -> PythonConvertible
> 
> I'm sure you have good reasons, it might make the implementation bleed out 
> into other parts of the codebase. It would be good to include it in the 
> proposal alternatives section though. At the moment most of the 
> "alternatives" in the proposal just seem to be extensions to the same 
> solution :)

I’m not sure what you’re getting at here.  The system I’ve sketched out does 
not incorporate Python declarations, everything is dynamic.  It is extremely 
simple.  This is a huge feature :-)  I think it is entirely non-scalable to do 
something like the ObjC importer for every language that Swift wants to interop 
with.

> Clarity
> Perhaps just that things are more clear to me now
> 
> If my extrapolation is correct a user will implement a single type that will 
> allow a subset of a good 

Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Howard Lovatt via swift-evolution
In Java you can have annotation processors, user supplied compiler extensions, 
that are extensively used for making frameworks easier to use and for general 
interfacing to ‘foreign stuff’.

Would a limited form of user supplied compiler extension be an alternative, an 
import processor. Special import syntax, import beginning with ‘Foreign’, would 
be recognised by the compiler and a user supplied import processor would be 
called, in the case of the example for Python. The import processor would 
generate the glue code. Below is a basic example to give a feel for what I am 
proposing.

(Syntax, names, etc. in code below just the 1st that came into my head!)

  — Howard.

==

import Foreign.Python.Foo // Special import tag `Foreign` calls a user supplied 
compiler extension that parses the imported Python and generates something 
along these lines (its up to the importer the exact code generated!):

protocol _ForeignPythonCallable {
func call(method: Any, arguments: Any...) throws -> Any
}

extension _ForeignPythonCallable {
func call(method: Any, arguments: Any...) throws -> Any {
return "method: \(method), arguments: \(arguments)" // Method lookup 
and calling code for Python.
}
}

class Foo: _ForeignPythonCallable {
// Could override `call` if more efficient than complete general lookup was 
possible.
enum _ForeignPythonMethodNames { // This might be a C struct so that it 
matches perfectly what the python interpreter is expecting.
case bar
}
enum _ForeignPythonMethodBarArguments { // This might be a C struct so that 
it matches perfectly what the python interpreter is expecting.
case x(Any)
case noName1(Any)
case y(Any)
}
func bar(x: Any, _ noName1: Any, y: Any) -> Any {
do {
return try call(method: _ForeignPythonMethodNames.bar, arguments: 
_ForeignPythonMethodBarArguments.x(x), 
_ForeignPythonMethodBarArguments.noName1(noName1), 
_ForeignPythonMethodBarArguments.y(y))
} catch {
fatalError("Method `bar` does not throw, therefore Python importer 
bug.")
}
}
}

// Then the consumer of `Foo` uses as per normal Swift:

let foo = Foo()
foo.bar(x: 1, 23, y: 17)

class TypedFoo: Foo { // For many dynamic languages this wouldn't be possible 
to automatically generate via the import, therefore would have to be hand 
written.
func bar(x: Int, _ noName1: Int, y: Int) -> String {
return super.bar(x: x, noName1, y: y) as! String
}
}
let typedFoo = TypedFoo()
typedFoo.bar(x: 1, 23, y: 17)


> On 12 Nov 2017, at 11:15 am, Andrew Bennett via swift-evolution 
>  wrote:
> 
> HI, this proposal looks really interesting!
> 
> I have a few questions:
> 
> Clarity on the proposal's intent
> Nice cheap bridges, or lowering barriers to bridging?
> 
> I can see this providing a nice quick interface to Python from Swift, but I'm 
> not sure if the exposed interface will be very Swifty (you probably have a 
> much better idea of what is Swifty ;) than I do though). It seems you want it 
> to be possible for everything to be dynamically exposed, I've used similar 
> with Lua's meta methods, and I found it to be very powerful, you could 
> basically implement inheritance in the language, which wasn't necessarily a 
> good thing in retrospect.
> 
> Is it common for the the argument labels in other languages to be open ended, 
> or are labels typically finite? If the answer is finite, why not use a Swift 
> method as the wrapper?
> Do you want duck typing, and would it be better to expose this via a protocol?
> 
> It seems like in almost every case you could do something like this:
> 
> func myMethod(a: X? = 
> nil, b: Y) {
> pythonBridge.call("myMethod", arguments: ["a": X, "b": Y])
> }
> 
> It might be good to add some use-cases (a popular Python library perhaps) to 
> the proposal where this type of bridge would be insufficient :).
> 
> It seems like this proposal pushes the responsibility of Swifty-ness and 
> type-safety to the caller. At some point you'll have to write a type-safe 
> bridging layer, or write your entire program in non-Swifty code ("The most 
> obvious way to write code should also behave in a safe manner"). Is the main 
> goal to lower the barrier to Python and other dynamic languages? or is it to 
> provide a cheap nice Swifty bridge? I have the above concerns about the 
> latter.
> 
> Alternative sugar
> 
> Ruby has Keyword Arguments for similar sugar:
> 
> def foo(regular, hash={})
> puts "the hash: #{hash}"
> 
> 
> I'm sure you're aware of it, but I'll explain for completeness, any trailing 
> argument labels are stored and passed as a hash:
> 
> foo(regular, bar: "hello", bas: 123) # outputs 'the hash: [bar: "hello", bas: 
> 123]'
> Have you considered an alternative like this? For example:
> 
> func myMethod(regular: Int, store: @argcapture [String: PythonConvertible]) 
> -> 

Re: [swift-evolution] async void

2017-11-11 Thread Yuta Koshizawa via swift-evolution
2017-11-12 2:57 GMT+09:00 Adam Kemp :
>
>
>> On Nov 11, 2017, at 6:24 AM, Yuta Koshizawa  wrote:
>>
>> If you replace `async` with `throws`, you can get answers.
>>
>>
>>> Can you declare an async closure variable?
>>
>> Yes. Like `let throwingClosure:() throws -> Void = { ... }`.
>>
>>
>>> Can a non-async closure be passed to a function expecting a async closure?
>>
>> Yes. Like we can pass `() -> Void` to a function expecting a throwing
>> closure `() throws -> Void`.
>>
>> It is possible because `(Foo) throws -> Bar` is a supertype of `(Foo)
>> -> Bar`. `(Foo) async -> Bar` is a supertype of `(Foo) -> Bar` in the
>> same way.
>>
>> To treat an async function as a sync function is legal. It is similar
>> to make a `Promise` by `Promise(value)` which is completed
>> immediately.
>>
>>
>>> Can an async closure be passed to a function expecting a non-async closure?
>>
>> No. `() -> Void` is a subtype of `() async -> Void`. It is same as
>> passing `() throws -> Void` to a function expecting `() -> Void` is
>> not allowed.
>
> But why not? Just asserting that it must work the same as throws
> is not a convincing argument. You have to justify why it must work
> that way. I think there is good reason to allow it, which I have described.
> What reason is there to disallow it?

`() async -> Void` needs to be called with `await` because it prevents
us from forgetting handling asynchronous operations.

If we use callbacks to handle asynchronous operations, it is shown to
us by a compiler as a compilation error.

```
func fooAsync(_ handler: () -> Void) -> Void { ... }

fooAsync() // compilation error

fooAsync {
  // handles a completion event here
}
```

With proposed `async/await`, it is realized similarly like below.

```
func fooAsync() async -> Void { ... }

fooAsync() // compilation error

await fooAsync()
// handles a completion event here
```

However, if async void functions work like `beginAsync`, we can easily
forget it and it can cause unexpected behaviors.

```
func fooAsync() async -> Void { ... }

fooAsync() // OK
// hard to know this line is executed asynchronously
```

Readability also suffers seriously. If we don't know `bar` in the
following code is a async function, it is impossible to expect lines
after `baz()` are executed asynchronously.

```
foo()
bar()
baz()
qux()
```


>>> It’s weird to me that we would allow you to have async void closures but 
>>> not async void functions
>>
>> I am not sure what you mean. "async void closures" and "async void
>> functions" have a same type. Following two are almost same.
>>
>> ```
>> func foo() async -> Void { ... }
>> let foo: () async -> Void = { ... }
>> ```
>
> What started this thread is my suggestion that you should be able to write
> an async void function. The current proposal doesn’t allow that. That’s why
> you have to use beginAsync.
>
> I don’t think that makes sense. It sounds like you also think that would be 
> strange,
> hence your assumption that you could.

By the reasons I wrote above, we need `await` even for async void
functions for checks by compilers. Then it is required to provide a
way to write entry points of async functions. That is `beginAsync`.

--
Yuta
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Andrew Bennett via swift-evolution
HI, this proposal looks really interesting!

I have a few questions:

*Clarity on the proposal's intent*
*Nice cheap bridges, or lowering barriers to bridging?*

I can see this providing a nice quick interface to Python from Swift, but
I'm not sure if the exposed interface will be very Swifty (you probably
have a much better idea of what is Swifty ;) than I do though). It seems
you want it to be possible for everything to be dynamically exposed, I've
used similar with Lua's meta methods, and I found it to be very powerful,
you could basically implement inheritance in the language, which wasn't
necessarily a good thing in retrospect.

Is it common for the the argument labels in other languages to be open
ended, or are labels typically finite? If the answer is finite, why not use
a Swift method as the wrapper?
Do you want duck typing, and would it be better to expose this via a
protocol?

It seems like in almost every case you could do something like this:

func myMethod(a: X?
= nil, b: Y) {

pythonBridge.call("myMethod", arguments: ["a": X, "b": Y])

}

It might be good to add some *use-cases* (a popular Python library perhaps)
to the proposal where this type of bridge would be insufficient :).

It seems like this proposal pushes the responsibility of Swifty-ness and
type-safety to the caller. At some point you'll have to write a type-safe
bridging layer, or write your entire program in non-Swifty code ("The most
obvious way to write code should also behave in a safe manner"). Is the
main goal to *lower the barrier to Python* and other dynamic languages? or
is it to provide a cheap nice Swifty bridge? I have the above concerns
about the latter.

*Alternative sugar*

Ruby has Keyword Arguments for similar sugar:

*def* foo(regular, hash={})
*puts* "the hash: #{hash}"


I'm sure you're aware of it, but I'll explain for completeness, any
trailing argument labels are stored and passed as a hash:

foo(regular, bar: "hello", bas: 123) *# outputs 'the hash: [**bar:
"hello", bas: 123]'*

Have you considered an alternative like this? For example:

func myMethod(regular: Int, store: @argcapture [String: PythonConvertible])
-> PythonConvertible

I'm sure you have good reasons, it might make the implementation bleed out
into other parts of the codebase. It would be good to include it in the
proposal *alternatives* section though. At the moment most of the
"alternatives" in the proposal just seem to be extensions to the same
solution :)

*Clarity*
*Perhaps just that things are more clear to me now*

If my extrapolation is correct a user will implement a single type that
will allow a subset of a good portion of another language to be exposed
(object method and property bridging). I'm guessing that the dynamic member
proposal you're planning will not work with methods, it will require a
property, I think this helps explain some of the motivations. It might be
nice to have a more complete example that includes dynamic members. I
didn't find it clear from the proposal that it would only be necessary to
implement this protocol once per language.

Thanks for considering my questions,
Andrew Bennett


On Sat, Nov 11, 2017 at 4:37 AM, Chris Lattner via swift-evolution <
swift-evolution@swift.org> wrote:

> Hello all,
>
> I have a couple of proposals cooking in a quest to make Swift interoperate
> with dynamically typed languages like Python better.  Instead of baking in
> hard coded support for one language or the other, I’m preferring to add a
> few small but general purpose capabilities to Swift.  This is the first,
> which allows a Swift type to become “callable”.
>
> The proposal is here:
> https://gist.github.com/lattner/a6257f425f55fe39fd6ac7a2354d693d
>
> I’ve also attached a snapshot below, but it will drift out of date as the
> proposal is refined.  Feedback and thoughts are appreciated, thanks!
>
> -Chris
>
>
>
>
>
> Introduce user-defined dynamically "callable" types
>
>- Proposal: SE-
>
>- Author: Chris Lattner 
>- Review Manager: TBD
>- Status: Awaiting implementation
>
>
> 
> Introduction
>
> This proposal introduces a new DynamicCallable protocol to the standard
> library. Types that conform to it are "callable" with the function call
> syntax. It is simple syntactic sugar which allows the user to write:
>
> a = someValue(keyword1: 42, "foo", keyword2: 19)
>
> and have it be interpreted by the compiler as:
>
>   a = someValue.dynamicCall(arguments: [
> ("keyword1", 42), ("", "foo"), ("keyword2", 19)
>   ])
>
> Other languages have analogous features (e.g. Python "callables"), but the
> primary motivation of this proposal is to allow elegant and natural
> interoperation with dynamic languages in Swift.
>
> Swift-evolution thread: Discussion thread topic for that proposal
> 

Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution
That makes sense. I can see how type providers are very handy for that.  I’m 
just curious how they help with the goal that this proposal is intended to 
address: being able to use arbitrary Python APIs from Swift.

If the barrier to entry is the requirement for users to write type signatures 
for all APIs you want to use, then many will just immediately turn away at the 
gate.  It also doesn’t appear to help *actually* dynamically polymorphic 
values, which occur in Python just like the occur in ObjC.

Type providers seem like something that conceptually could be a useful 
refinement for my pitch: improving some APIs in some cases.  I don’t see how it 
is a replacement, which seems to be what Joe was saying.  

-Chris

> On Nov 11, 2017, at 2:17 PM, Alejandro Martinez  wrote:
> 
> If it helps, for what I understand (in Typescript with things like
> http://definitelytyped.org ) the idea with type providers is that
> someone write the type definitions for dynamic code to basically
> provide a more "typed" version of the API that can be consumed in a
> more static language.
> 
> On Sat, Nov 11, 2017 at 9:57 PM, Chris Lattner via swift-evolution
>  wrote:
>> 
>> 
>> On Nov 11, 2017, at 10:17 AM, Chris Lattner via swift-evolution
>>  wrote:
>> 
>> so I don't think there's a time constraint forcing us to consider the
>> "narrow" vs "huge" dimension. What's the best thing for the language and
>> tools in the long term? This is a feature that influences the semantics of
>> potentially any call site in all Swift code, which we'd have to live with
>> forever if we accepted it now. Opening up the compiler architecture to make
>> custom importers easier to write is a great solution to a ton of problems,
>> including yours I think, without adding complexity to the core language.
>> Experience in .NET land seems to show it's a great technique for integrating
>> dynamic systems with static type systems, without poking unnecessary holes
>> in the static language's type system
>> 
>> 
>> As I mentioned, I’m not familiar with F# type providers.  As I told you
>> upthread, I will read about them and respond with an informed opinion when I
>> have time.
>> 
>> 
>> I have done some quick reading about type providers, but I am certainly not
>> an expert.  I have a couple of questions that I’d appreciate your insight
>> on:
>> 
>> Type providers seem like a (complicated!) compile-time form of meta
>> programming or compiler plugin.  How does this help interoperability with
>> dynamic languages, where the preponderance of values have types that are not
>> knowable at compile time?
>> 
>> To pick a specific example you are familiar with, this seems like it could
>> help in theory (though I suspect it would be be entirely impractical in
>> practice) to provide types for Objective-C methods that are coming from an
>> SDK where you have declarations.
>> 
>> In contrast, it does *not* seem like it would help with the problem of
>> resolving members of “id” typed values in Objective-C, which is the crux of
>> the dynamic language problem.  If my understanding is correct, type
>> providers seem completely unhelpful for python interoperability, because you
>> don’t know the types of python values: anything loaded from a Python
>> property or returned by a Python function is the equivalent of “id”.
>> 
>> It’s entirely possible I’m missing something big.  If so, I’d appreciate a
>> pointer to something to read that explains how this works.  Thanks!
>> 
>> -Chris
>> 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
> 
> 
> 
> -- 
> Alejandro Martinez
> http://alejandromp.com
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution
Ok, which differences?

-Chris

> On Nov 11, 2017, at 2:19 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPad
> 
>> On Nov 11, 2017, at 11:40 AM, Chris Lattner  wrote:
>> 
>> On Nov 10, 2017, at 6:10 PM, Matthew Johnson via swift-evolution 
>>  wrote:
> On Nov 10, 2017, at 11:25 AM, Matthew Johnson via swift-evolution 
>  wrote:
> 
>>> 
>>> People have reasonably asked for the ability to make their own 
>>> function-like types in the past, such that "myvalue(...)" behaves like 
>>> sugar for "myvalue.call(...)" or something like that. In most cases, 
>>> they still want to have type system control over what arguments and 
>>> results their call operation produces. They don't really get that with 
>>> this proposal; they lose all control over the arity and argument types. 
>> 
>> As I mentioned, this is directly addressed in the writeup. Here’s the 
>> link:
>> https://gist.github.com/lattner/a6257f425f55fe39fd6ac7a2354d693d#staticly-checking-for-exact-signatures
> 
> That discusses why you didn’t include it in the present proposal but I 
> think it’s reasonable to oppose adding a dynamic callable feature prior 
> to a more Swifty static callable.
 
 Why?  One does not preclude the other.
>>> 
>>> For exactly the reason Joe articulates.  Some people will use what the 
>>> language offers to get the syntax they desire even if it sacrifices type 
>>> safety.  If we’re going to have first-class callable types in Swift (I 
>>> think it’s a great idea) type safety for native code should be prioritized 
>>> over syntactic convenience for dynamic language interop.  We can have both, 
>>> but the former should come first IMO.
>> 
>> Hi Matthew,
>> 
>> In point of fact, Swift already has the feature you are referring to.  It 
>> just spells it with square brackets instead of parentheses.  A simple change 
>> to the punctuation character has much less point than the proposal that I’m 
>> pitching.
> 
> This is true if you squint, but I imagine a design for callable types would 
> include some 
>  differences other than just punctuation.
> 
>> 
>> -Chris
>> 
>> 
> ___
> 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


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Matthew Johnson via swift-evolution


Sent from my iPad

> On Nov 11, 2017, at 11:40 AM, Chris Lattner  wrote:
> 
> On Nov 10, 2017, at 6:10 PM, Matthew Johnson via swift-evolution 
>  wrote:
 On Nov 10, 2017, at 11:25 AM, Matthew Johnson via swift-evolution 
  wrote:
 
>> 
>> People have reasonably asked for the ability to make their own 
>> function-like types in the past, such that "myvalue(...)" behaves like 
>> sugar for "myvalue.call(...)" or something like that. In most cases, 
>> they still want to have type system control over what arguments and 
>> results their call operation produces. They don't really get that with 
>> this proposal; they lose all control over the arity and argument types. 
> 
> As I mentioned, this is directly addressed in the writeup. Here’s the 
> link:
> https://gist.github.com/lattner/a6257f425f55fe39fd6ac7a2354d693d#staticly-checking-for-exact-signatures
 
 That discusses why you didn’t include it in the present proposal but I 
 think it’s reasonable to oppose adding a dynamic callable feature prior to 
 a more Swifty static callable.
>>> 
>>> Why?  One does not preclude the other.
>> 
>> For exactly the reason Joe articulates.  Some people will use what the 
>> language offers to get the syntax they desire even if it sacrifices type 
>> safety.  If we’re going to have first-class callable types in Swift (I think 
>> it’s a great idea) type safety for native code should be prioritized over 
>> syntactic convenience for dynamic language interop.  We can have both, but 
>> the former should come first IMO.
> 
> Hi Matthew,
> 
> In point of fact, Swift already has the feature you are referring to.  It 
> just spells it with square brackets instead of parentheses.  A simple change 
> to the punctuation character has much less point than the proposal that I’m 
> pitching.

This is true if you squint, but I imagine a design for callable types would 
include some 
 differences other than just punctuation.

> 
> -Chris
> 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Alejandro Martinez via swift-evolution
If it helps, for what I understand (in Typescript with things like
http://definitelytyped.org ) the idea with type providers is that
someone write the type definitions for dynamic code to basically
provide a more "typed" version of the API that can be consumed in a
more static language.

On Sat, Nov 11, 2017 at 9:57 PM, Chris Lattner via swift-evolution
 wrote:
>
>
> On Nov 11, 2017, at 10:17 AM, Chris Lattner via swift-evolution
>  wrote:
>
> so I don't think there's a time constraint forcing us to consider the
> "narrow" vs "huge" dimension. What's the best thing for the language and
> tools in the long term? This is a feature that influences the semantics of
> potentially any call site in all Swift code, which we'd have to live with
> forever if we accepted it now. Opening up the compiler architecture to make
> custom importers easier to write is a great solution to a ton of problems,
> including yours I think, without adding complexity to the core language.
> Experience in .NET land seems to show it's a great technique for integrating
> dynamic systems with static type systems, without poking unnecessary holes
> in the static language's type system
>
>
> As I mentioned, I’m not familiar with F# type providers.  As I told you
> upthread, I will read about them and respond with an informed opinion when I
> have time.
>
>
> I have done some quick reading about type providers, but I am certainly not
> an expert.  I have a couple of questions that I’d appreciate your insight
> on:
>
> Type providers seem like a (complicated!) compile-time form of meta
> programming or compiler plugin.  How does this help interoperability with
> dynamic languages, where the preponderance of values have types that are not
> knowable at compile time?
>
> To pick a specific example you are familiar with, this seems like it could
> help in theory (though I suspect it would be be entirely impractical in
> practice) to provide types for Objective-C methods that are coming from an
> SDK where you have declarations.
>
> In contrast, it does *not* seem like it would help with the problem of
> resolving members of “id” typed values in Objective-C, which is the crux of
> the dynamic language problem.  If my understanding is correct, type
> providers seem completely unhelpful for python interoperability, because you
> don’t know the types of python values: anything loaded from a Python
> property or returned by a Python function is the equivalent of “id”.
>
> It’s entirely possible I’m missing something big.  If so, I’d appreciate a
> pointer to something to read that explains how this works.  Thanks!
>
> -Chris
>
>
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>



-- 
Alejandro Martinez
http://alejandromp.com
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-11 Thread Michel Fortin via swift-evolution
Oh right. I guess that makes most of my review beside the point then. Sorry.

> Le 11 nov. 2017 à 14:46, BJ Homer  > a écrit :
> 
> 
> 
>> On Nov 11, 2017, at 9:49 AM, Michel Fortin via swift-evolution 
>> > wrote:
>> 
>> I think it fits well for arrays. Not sure about optionals.
> 
> This proposal only suggests changing the one on sequences, and even then, not 
> all of them. Currently, the following exist:
> 
> // Reminder: Int("someString") returns 'Int?' in the following examples
> 
> // (1) Sequence.flatMap() with a closure returning an optional, dropping 
> anything that maps to nil
> ["1", "mountain", "2"].flatMap({ Int($0) })  // [1, 2]
> 
> // (2) Sequence.flatMap() with a closure returning a sequence, then joining 
> (“flattening”) them into one array
> [1, 2, 3].flatMap({ Array(1...$0) }) // [1, 1, 2, 1, 2, 3]
> 
> // (3) Optional.flatMap() with a closure returning an optional, flattening a 
> nested optional.
> ("3" as String?).flatMap({ Int($0) }) // Optional(3)
> 
> 
> The 2nd and 3rd variants are both about flattening nested structures, and 
> would not change under this proposal. We would keep calling them “flatMap()”. 
> There is no a proposal to add Optional.filterMap, nor to change the 
> Sequence.flatMap variant that flattens nested sequences. The only change 
> proposed it is to rename the first one.
> 
> -BJ

-- 
Michel Fortin
https://michelf.ca 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Eagle Offshore via swift-evolution
They're called Blocks.  Objective C has them.  They're objects.  They're 
actually Objective C objects.

> On Nov 10, 2017, at 10:26 AM, Florent Vilmart via swift-evolution 
>  wrote:
> 
> Object that are functions too, Amazing! I wanted that in Javascript for a 
> while!
> 
> On Nov 10, 2017, 1:04 PM -0500, Joe Groff via swift-evolution 
> , wrote:
>> I don't like the idea of some calls having wildly different semantics from 
>> others; it's difficult enough to tell what exactly a call might be doing 
>> already. Since we also lack the more obvious static "Callable" protocol idea 
>> to give even well-typed call syntax to user-defined types, this also seems 
>> like it'd be easily abused for that purpose too.
>> 
>> I think a much better general solution to the problem of "make dynamic 
>> systems interact with type systems" is something like F#'s type providers 
>> which lets you write your own importers that look at dynamic information 
>> from a database, dynamic language VM, or some other system and generate type 
>> information usable by the compiler. Integration at the importer level could 
>> let you produce more well-typed Swift declarations by looking at the runtime 
>> information you get by importing a Python module.
>> 
>> -Joe
>> 
>>> On Nov 10, 2017, at 9:37 AM, Chris Lattner via swift-evolution 
>>>  wrote:
>>> 
>>> Hello all,
>>> 
>>> I have a couple of proposals cooking in a quest to make Swift interoperate 
>>> with dynamically typed languages like Python better. Instead of baking in 
>>> hard coded support for one language or the other, I’m preferring to add a 
>>> few small but general purpose capabilities to Swift. This is the first, 
>>> which allows a Swift type to become “callable”.
>>> 
>>> The proposal is here:
>>> https://gist.github.com/lattner/a6257f425f55fe39fd6ac7a2354d693d
>>> 
>>> I’ve also attached a snapshot below, but it will drift out of date as the 
>>> proposal is refined. Feedback and thoughts are appreciated, thanks!
>>> 
>>> -Chris
>>> 
>>> 
>>> 
>>> 
>>> 
>>> Introduce user-defined dynamically "callable" types
>>> 
>>> • Proposal: SE-
>>> • Author: Chris Lattner
>>> • Review Manager: TBD
>>> • Status: Awaiting implementation
>>> Introduction
>>> 
>>> This proposal introduces a new DynamicCallable protocol to the standard 
>>> library. Types that conform to it are "callable" with the function call 
>>> syntax. It is simple syntactic sugar which allows the user to write:
>>> 
>>> a = someValue(keyword1: 42, "foo", keyword2: 19)
>>> and have it be interpreted by the compiler as:
>>> 
>>> a = someValue.dynamicCall(arguments
>>> : [
>>> (
>>> "keyword1", 42), ("", "foo"), ("keyword2", 19
>>> )
>>> ])
>>> 
>>> Other languages have analogous features (e.g. Python "callables"), but the 
>>> primary motivation of this proposal is to allow elegant and natural 
>>> interoperation with dynamic languages in Swift.
>>> 
>>> Swift-evolution thread: Discussion thread topic for that proposal
>>> 
>>> Motivation
>>> 
>>> Swift is well known for being exceptional at interworking with existing C 
>>> and Objective-C APIs, but its support for calling APIs written in scripting 
>>> langauges like Python, Perl, and Ruby is quite lacking. These languages 
>>> provide an extremely dynamic programming model where almost everything is 
>>> discovered at runtime.
>>> 
>>> Through the introduction of this proposal, and the related 
>>> DynamicMemberLookupProtocol proposal, we seek to fix this problem. We 
>>> believe we can make many common APIs feel very natural to use directly from 
>>> Swift without all the complexity of implementing something like the Clang 
>>> importer. For example, consider this Python code:
>>> 
>>> class Dog
>>> :
>>> 
>>> def __init__(self, name
>>> ):
>>> 
>>> self.name =
>>> name
>>> 
>>> self.tricks = [] # creates a new empty list for each dog
>>> 
>>> 
>>> 
>>> def add_trick(self, trick
>>> ):
>>> 
>>> self.tricks.append(trick)
>>> we would like to be able to use this from Swift like this (the comments 
>>> show the corresponding syntax you would use in Python):
>>> 
>>> // import DogModule
>>> // import DogModule.Dog as Dog // an alternate
>>> let Dog = Python.import(“DogModule.Dog")
>>> 
>>> // dog = Dog("Brianna")
>>> let dog = Dog("Brianna")
>>> 
>>> // dog.add_trick("Roll over")
>>> dog.add_trick("Roll over")
>>> 
>>> // dog2 = Dog("Kaylee").add_trick("snore")
>>> let dog2 = Dog("Kaylee").add_trick("snore")
>>> Of course, this would also apply to standard Python APIs as well. Here is 
>>> an example working with the Python pickleAPI and the builtin Python 
>>> function open:
>>> 
>>> // import pickle
>>> let pickle = Python.import("pickle"
>>> )
>>> 
>>> 
>>> // file = open(filename)
>>> let file = Python.open
>>> (filename)
>>> 
>>> 
>>> // blob = file.read()
>>> let blob = file.read
>>> ()
>>> 
>>> 
>>> // result = pickle.loads(blob)
>>> let result = pickle.loads(blob)

Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution


> On Nov 11, 2017, at 10:17 AM, Chris Lattner via swift-evolution 
>  wrote:
> 
>> so I don't think there's a time constraint forcing us to consider the 
>> "narrow" vs "huge" dimension. What's the best thing for the language and 
>> tools in the long term? This is a feature that influences the semantics of 
>> potentially any call site in all Swift code, which we'd have to live with 
>> forever if we accepted it now. Opening up the compiler architecture to make 
>> custom importers easier to write is a great solution to a ton of problems, 
>> including yours I think, without adding complexity to the core language. 
>> Experience in .NET land seems to show it's a great technique for integrating 
>> dynamic systems with static type systems, without poking unnecessary holes 
>> in the static language's type system
> 
> As I mentioned, I’m not familiar with F# type providers.  As I told you 
> upthread, I will read about them and respond with an informed opinion when I 
> have time.

I have done some quick reading about type providers, but I am certainly not an 
expert.  I have a couple of questions that I’d appreciate your insight on:

Type providers seem like a (complicated!) compile-time form of meta programming 
or compiler plugin.  How does this help interoperability with dynamic 
languages, where the preponderance of values have types that are not knowable 
at compile time?

To pick a specific example you are familiar with, this seems like it could help 
in theory (though I suspect it would be be entirely impractical in practice) to 
provide types for Objective-C methods that are coming from an SDK where you 
have declarations.  

In contrast, it does *not* seem like it would help with the problem of 
resolving members of “id” typed values in Objective-C, which is the crux of the 
dynamic language problem.  If my understanding is correct, type providers seem 
completely unhelpful for python interoperability, because you don’t know the 
types of python values: anything loaded from a Python property or returned by a 
Python function is the equivalent of “id”.

It’s entirely possible I’m missing something big.  If so, I’d appreciate a 
pointer to something to read that explains how this works.  Thanks!

-Chris

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-dev] Re-pitch: Deriving collections of enum cases

2017-11-11 Thread Xiaodi Wu via swift-evolution
On Sat, Nov 11, 2017 at 3:15 PM, Tony Allevato 
wrote:

>
>
> On Sat, Nov 11, 2017 at 10:28 AM Xiaodi Wu  wrote:
>
>> On Sat, Nov 11, 2017 at 11:23 AM, Tony Allevato 
>> wrote:
>>
>>>
>>>
>>> On Fri, Nov 10, 2017 at 11:01 PM Xiaodi Wu via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
 Nit: if you want to call it `ValueEnumerable`, then this should be
 `DefaultValueCollection`.

 More generally though, I can see the appeal of allowing `Int` to
 conform to `ValueEnumerable`, but I've got a feeling that this is headed
 rapidly in the direction of overengineering a feature without a good
 rationale for the additional complexity. The stated use case is to
 enumerate the cases of an enum, and any additional complexity above that
 should stand on its own merit. I disagree quite vehemently that protocols
 should be "as general as possible"; rather, they exist to enable useful
 generic algorithms and should be as _useful_ as possible. There is a happy
 medium beyond which overengineering the design makes a protocol markedly
 less usable/approachable for the sake of enabling rare functionality.

>>>
>>> Perhaps "no more specific than they need to be" would have been a better
>>> choice of words on my part than "as general as possible".
>>>
>>> I'm not sure why you think this decision makes the protocol "markedly
>>> less usable/approachable". and I think you're seeing a lot of complexity
>>> that isn't there. Regarding good rationale, I've given that in this thread
>>> above and in the previous discussion thread, but I'll summarize it again
>>> here:
>>>
>>> 1) "The stated use case is to enumerate the cases of an enum" isn't
>>> sufficient for designing a protocol because Swift does not have protocols
>>> that are restricted only to enums. Just as anyone can conform their own
>>> types to RawRepresentable, anyone should be able to conform their own types
>>> to ValueEnumerable.
>>>
>>
>> This is the part of the argument that I am questioning. If the desired
>> use case is to enumerate the cases of an enum, is it much of a gain to
>> allow anyone to be able to conform their own non-enum types to this
>> protocol? Yes, if you buy that, then much of the rest follows. But make no
>> mistake that it is not necessary to serve the desired use case and
>> dramatically increases the complexity of the design (see below for just
>> some considerations).
>>
>
> Some increase in complexity is certainly going to be introduced by
> generalizing a design to make it useful to more than just a single use
> case, but I hope you understand that using unquantifiable and subjective
> qualifiers like "markedly less usable" or "dramatically increases the
> complexity" is a bit unhelpful when trying to debate specifics. You clearly
> put a great deal of thought into design problems like this and I always
> appreciate your points of view, so I want to focus on the objective parts.
>
> In prior threads on this topic, I believe I recall you saying that a
> static property that returns an array is fine. (I don't remember your exact
> words, so please correct me if I'm wrong. I don't want to misstate your
> position.) Given the concerns I've pointed out about why that is both a
> time and memory performance problem, and given your focus on the common use
> case above, I'd appreciate your opinion on these points:
>
> * Are you advocating for a magic protocol that *only* enums can conform
> to? (This is a different issue than whether the protocol is just a
> compiler-known protocol that it can synthesize.)
> * If yes, why intentionally restrict it others from implementing the
> protocol? That's actually *more* complexity than allowing it, like we do
> with RawRepresentable. There's also no precedent for "a protocol that can
> only be applied to enums" in the Swift language. The ramifications of that
> decision introduce their own design complexity—you're just shifting it
> around, not avoiding it.
> * If no, then I don't think we differ on this point.
>

No magic. Consider: Does the compiler stop me from conforming `UIButton` to
`Error`? No. Can `UIButton` conform to `Error`? Semantically, no.

I am arguing that the use case justifies a protocol called "CaseEnumerable"
with documented semantics such that only types with cases (i.e., enums with
one or more cases) would fulfill those semantics. Any more generalization
and we are designing without a justification. I'm unsure what design
complexity you anticipate with such a definition of "CaseEnumerable."

* Do you think that the type of this property should still be an array,
> with all of the performance problems that it brings, or would you find a
> sufficiently array-like but more performant type to be fine?
>

I have no problem with any suitable type if it can be justified, say, on
the grounds of performance or memory efficiency. I do have a 

Re: [swift-evolution] [swift-dev] Re-pitch: Deriving collections of enum cases

2017-11-11 Thread Tony Allevato via swift-evolution
On Sat, Nov 11, 2017 at 10:28 AM Xiaodi Wu  wrote:

> On Sat, Nov 11, 2017 at 11:23 AM, Tony Allevato 
> wrote:
>
>>
>>
>> On Fri, Nov 10, 2017 at 11:01 PM Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>>> Nit: if you want to call it `ValueEnumerable`, then this should be
>>> `DefaultValueCollection`.
>>>
>>> More generally though, I can see the appeal of allowing `Int` to conform
>>> to `ValueEnumerable`, but I've got a feeling that this is headed rapidly in
>>> the direction of overengineering a feature without a good rationale for the
>>> additional complexity. The stated use case is to enumerate the cases of an
>>> enum, and any additional complexity above that should stand on its own
>>> merit. I disagree quite vehemently that protocols should be "as general as
>>> possible"; rather, they exist to enable useful generic algorithms and
>>> should be as _useful_ as possible. There is a happy medium beyond which
>>> overengineering the design makes a protocol markedly less
>>> usable/approachable for the sake of enabling rare functionality.
>>>
>>
>> Perhaps "no more specific than they need to be" would have been a better
>> choice of words on my part than "as general as possible".
>>
>> I'm not sure why you think this decision makes the protocol "markedly
>> less usable/approachable". and I think you're seeing a lot of complexity
>> that isn't there. Regarding good rationale, I've given that in this thread
>> above and in the previous discussion thread, but I'll summarize it again
>> here:
>>
>> 1) "The stated use case is to enumerate the cases of an enum" isn't
>> sufficient for designing a protocol because Swift does not have protocols
>> that are restricted only to enums. Just as anyone can conform their own
>> types to RawRepresentable, anyone should be able to conform their own types
>> to ValueEnumerable.
>>
>
> This is the part of the argument that I am questioning. If the desired use
> case is to enumerate the cases of an enum, is it much of a gain to allow
> anyone to be able to conform their own non-enum types to this protocol?
> Yes, if you buy that, then much of the rest follows. But make no mistake
> that it is not necessary to serve the desired use case and dramatically
> increases the complexity of the design (see below for just some
> considerations).
>

Some increase in complexity is certainly going to be introduced by
generalizing a design to make it useful to more than just a single use
case, but I hope you understand that using unquantifiable and subjective
qualifiers like "markedly less usable" or "dramatically increases the
complexity" is a bit unhelpful when trying to debate specifics. You clearly
put a great deal of thought into design problems like this and I always
appreciate your points of view, so I want to focus on the objective parts.

In prior threads on this topic, I believe I recall you saying that a static
property that returns an array is fine. (I don't remember your exact words,
so please correct me if I'm wrong. I don't want to misstate your position.)
Given the concerns I've pointed out about why that is both a time and
memory performance problem, and given your focus on the common use case
above, I'd appreciate your opinion on these points:

* Are you advocating for a magic protocol that *only* enums can conform to?
(This is a different issue than whether the protocol is just a
compiler-known protocol that it can synthesize.)
* If yes, why intentionally restrict it others from implementing the
protocol? That's actually *more* complexity than allowing it, like we do
with RawRepresentable. There's also no precedent for "a protocol that can
only be applied to enums" in the Swift language. The ramifications of that
decision introduce their own design complexity—you're just shifting it
around, not avoiding it.
* If no, then I don't think we differ on this point.

* Do you think that the type of this property should still be an array,
with all of the performance problems that it brings, or would you find a
sufficiently array-like but more performant type to be fine?


>
>> And once that's allowed, they should be able to do so without imposing an
>> overly restrictive API. What if a custom type has thousands of elements
>> that are easily computed sequentially or from an index? Forcing an Array on
>> the implementor is an unnecessary restriction and a burden. (More on this
>> below.)
>>
>> 2) There is *no decrease in usability for the common use case *by
>> choosing to make the protocol associated type a Sequence instead of a
>> Collection or Array because the concrete type synthesized by the compiler 
>> *would
>> be a more refined concrete type anyway.* In other words, anyone who
>> writes "MyEnum.allValues" would get back an integer-indexable random access
>> collection. I can imagine useful algorithms (more of an
>> algebraic/set-theoretical nature) that could be written for types with
>> 

Re: [swift-evolution] [Review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-11 Thread BJ Homer via swift-evolution


> On Nov 11, 2017, at 9:49 AM, Michel Fortin via swift-evolution 
>  wrote:
> 
> I think it fits well for arrays. Not sure about optionals.

This proposal only suggests changing the one on sequences, and even then, not 
all of them. Currently, the following exist:

// Reminder: Int("someString") returns 'Int?' in the following examples

// (1) Sequence.flatMap() with a closure returning an optional, dropping 
anything that maps to nil
["1", "mountain", "2"].flatMap({ Int($0) })  // [1, 2]

// (2) Sequence.flatMap() with a closure returning a sequence, then joining 
(“flattening”) them into one array
[1, 2, 3].flatMap({ Array(1...$0) }) // [1, 1, 2, 1, 2, 3]

// (3) Optional.flatMap() with a closure returning an optional, flattening a 
nested optional.
("3" as String?).flatMap({ Int($0) }) // Optional(3)


The 2nd and 3rd variants are both about flattening nested structures, and would 
not change under this proposal. We would keep calling them “flatMap()”. There 
is no a proposal to add Optional.filterMap, nor to change the Sequence.flatMap 
variant that flattens nested sequences. The only change proposed it is to 
rename the first one.

-BJ___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Joe Groff via swift-evolution


> On Nov 11, 2017, at 10:52 AM, Xiaodi Wu  wrote:
> 
>> On Sat, Nov 11, 2017 at 12:39 PM, Joe Groff via swift-evolution 
>>  wrote:
>> 
>> 
>>> On Nov 11, 2017, at 10:12 AM, Chris Lattner  wrote:
>>> 
>>> On Nov 11, 2017, at 6:52 AM, Joe Groff via swift-evolution 
>>>  wrote:
>> 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.
> 
> I’m pretty sure it doesn’t, but good news: since Swift requires an 
> implementation before the proposal can be officially reviewed, you will 
> be able to look at the actual patch to make this decision.
 
 And the goal of the pitch phase is to hopefully save you the tears of 
 trying to implement something if it's a bad idea.
>>> 
>>> Appreciated.  Fortunately I enjoy coding so it’s not that big of a deal for 
>>> me.
>>> 
>> 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.
> 
> This is really gross.  The goal here is to make Python feel natural.  If 
> you oppose this proposal then we’ll have to find some other way to 
> provide an elegant experience:
>> x∫(0, "foo", bar: "bas”)
> 
> This is not going to be acceptable to users.
 
 Is it? My choice of operator character is silly, but it's the same amount 
 of syntactic overhead as an optional chain/force call. It's a fair sight 
 better than x.call(args: ..., keywordArgs: ...), I hope you'd agree, and 
 is something that works without any language change.
>>> 
>>> Yes, I’m happy to explore that, and I agree this approach doesn’t require 
>>> language changes.  That said, there are three things you should understand:
>>> 
>>> 1) Details matter.  While you claim that there is some other operator 
>>> character that could be awesome, I’m not seeing it.  Can you try harder to 
>>> come up with something that you think would be acceptable?
>>> 
>>> 2) The point of the entire proposal is that a certain audience will be 
>>> using the feature enabled by this (python interop) *a lot*, so ergonomics 
>>> matter.
>>> 
>>> 3) This feature (python interop) is aimed to get Python programmers to 
>>> convert to Swift, not simply to ease friction for existing Swift 
>>> programmers (most of whom are iOS developers, to whom this feature is 
>>> completely irrelevant).  Getting people to move from Python to Swift is a 
>>> challenge, and syntax does actually matter. I hope we can agree that 
>>> expanding the community of Swift developers is a laudable goal.  
>> 
>> Sure. I suggest it not as a final endpoint but as incremental progress you 
>> can make with the language today. If you can get some early adopters 
>> interested in moving from Python to Swift with some small warts now and the 
>> promise of refined syntax in the future, that could let you make progress 
>> while we work out the right final model for dynamic language interop.
> 
> As a community member, I have to say that this part of the core team response 
> to the pitch has been the most dismaying part. It is quite evident to all, 
> I'm sure, that the ergonomics and approachability of Python is one of the 
> major draws for its audience. If Python interop in Swift is to gain traction 
> with that audience, it is pretty clear that anything short of `foo.bar(42)` 
> is not going to cut it. Overall, the response to a proposed design to achieve 
> that goal seems to be focused not on the design but on that goal itself, and 
> the gist of the response I'm sensing is "not now, if ever," or "current Swift 
> users first, new Swift users later." If a final model for dynamic language 
> interop is what's necessary before any headway is made in this space, then it 
> would seem to me that it is tantamount to shutting down the conversation here.

I'm sorry for discouraging discussion. I shouldn't have implied that this was a 
desirable endpoint, I was trying to figure out how far you can get in the 
language today, and highlight the availability of runtime metadata that could 
make other approaches more viable than the proposal suggested, and I should've 
connected those dots more clearly. To be clear, I think this is an interesting 
problem to solve, and I don't want to shut down conversation. Chris evaluated 
several approaches and picked one, and it's not the one I would pick. 
Ultimately, I want to do what's right for the language. I am not "the Core 
Team" in whole, I'm a 

Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Xiaodi Wu via swift-evolution
On Sat, Nov 11, 2017 at 12:39 PM, Joe Groff via swift-evolution <
swift-evolution@swift.org> wrote:

>
>
> On Nov 11, 2017, at 10:12 AM, Chris Lattner  wrote:
>
> On Nov 11, 2017, at 6:52 AM, Joe Groff via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> 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.
>
>
> I’m pretty sure it doesn’t, but good news: since Swift requires an
> implementation before the proposal can be officially reviewed, you will be
> able to look at the actual patch to make this decision.
>
>
> And the goal of the pitch phase is to hopefully save you the tears of
> trying to implement something if it's a bad idea.
>
>
> Appreciated.  Fortunately I enjoy coding so it’s not that big of a deal
> for me.
>
> 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.
>
>
> This is really gross.  The goal here is to make Python feel natural.  If
> you oppose this proposal then we’ll have to find some other way to provide
> an elegant experience:
>
> x∫(0, "foo", bar: "bas”)
>
>
> This is not going to be acceptable to users.
>
>
> Is it? My choice of operator character is silly, but it's the same amount
> of syntactic overhead as an optional chain/force call. It's a fair sight
> better than x.call(args: ..., keywordArgs: ...), I hope you'd agree, and is
> something that works without any language change.
>
>
> Yes, I’m happy to explore that, and I agree this approach doesn’t require
> language changes.  That said, there are three things you should understand:
>
> 1) Details matter.  While you claim that there is some other operator
> character that could be awesome, I’m not seeing it.  Can you try harder to
> come up with something that you think would be acceptable?
>
> 2) The point of the entire proposal is that a certain audience will be
> using the feature enabled by this (python interop) *a lot*, so ergonomics
> matter.
>
> 3) This feature (python interop) is aimed to get Python programmers to
> convert to Swift, not simply to ease friction for existing Swift
> programmers (most of whom are iOS developers, to whom this feature is
> completely irrelevant).  Getting people to move from Python to Swift is a
> challenge, and syntax does actually matter. I hope we can agree that
> expanding the community of Swift developers is a laudable goal.
>
>
> Sure. I suggest it not as a final endpoint but as incremental progress you
> can make with the language today. If you can get some early adopters
> interested in moving from Python to Swift with some small warts now and the
> promise of refined syntax in the future, that could let you make progress
> while we work out the right final model for dynamic language interop.
>

As a community member, I have to say that this part of the core team
response to the pitch has been the most dismaying part. It is quite evident
to all, I'm sure, that the ergonomics and approachability of Python is one
of the major draws for its audience. If Python interop in Swift is to gain
traction with that audience, it is pretty clear that anything short of
`foo.bar(42)` is not going to cut it. Overall, the response to a proposed
design to achieve that goal seems to be focused not on the design but on
that goal itself, and the gist of the response I'm sensing is "not now, if
ever," or "current Swift users first, new Swift users later." If a final
model for dynamic language interop is what's necessary before any headway
is made in this space, then it would seem to me that it is tantamount to
shutting down the conversation here.

Since you have long term ambitions in this space, I think it'd pay off to
> consider more infrastructurally-heavy features with bigger long-term
> payoffs.
>
>
> You mentioned variadics as being inadequate for your purposes as a
> considered alternative, but a variadics model that wasn't based on type
> erasure to arrays and kept runtime type information about the argument
> tuple that was passed in, along with better reflection APIs for accessing
> that type info, might lead to something you can use by incrementally
> improving the expressivity of existing language features instead of adding
> new ones.
>
>
> I’m not sure what you mean by this: variadics are fine. The hard part is
> getting the keyword arguments for a call dynamically.  Can you point to
> what you’re referring to in the proposal?
>
>
> I was referring to your comment in this section:
>
> Statically checking for exact signatures
>
> This proposal does not allow a type to specify an 

Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Joe Groff via swift-evolution


> On Nov 11, 2017, at 10:33 AM, Chris Lattner  wrote:
> 
> 
> 
>> On Nov 11, 2017, at 10:15 AM, Joe Groff via swift-evolution 
>>  wrote:
>> 
>> 
>> 
>>> On Nov 11, 2017, at 10:04 AM, Chris Lattner  wrote:
>>> 
>>> 
>>> 
> On Nov 11, 2017, at 6:29 AM, Joe Groff via swift-evolution 
>  wrote:
> 
> below the fold as far as the rest of the language is concerned. You could 
> just as well written what the importer synths up in Swift directly:
> 
> func foo(bar: String) {
> unsafeBitCast(objc_msgSend, to: @convention(c) (AnyObject, Selector, 
> NSString) -> ().self)(self, "fooWithBar:", NSString(bar))
> }
> 
> and the rest of the language would be none the wiser.
 
 Though, since you bring up objc_msgSend, the way it works in ObjC might be 
 a better fit for Swift's name lookup model, since their keyword argument 
 models are similar. If Swift had a 'method of last resort' like ObjC's
>>> 
>>> In fact, this is the subject of the next proposal that I will write up when 
>>> I have time.
>> 
>> It seems to me like a dynamic method-of-last-resort feature would subsume 
>> this proposal. Out of curiosity, why would we need both?
> 
> It seems that you missed the "[Discussion] Swift for Data Science / ML / Big 
> Data analytics” thread, in which a lot of context was discussed, as well as 
> multiple design approaches.  

Mea culpa, though data science is not my forte so I wouldn't have noised up a 
thread with that topic without being asked to.

> In any case, I will summarize here:
> 
> There are two fundamental operations that need to be supported to make a big 
> impact on dynamic language interop: member lookup and calls.
> 
> Many languages treat these as separable concepts.  In Python for example, 
> these are equivalent:
> 
>   return foo.bar(x: 1, 23, y: 17)
> and:
>   a = foo.bar
>   return a(x: 1, 23, y: 17)
> 
> Swift and the other Smalltalk inspired languages are the odd ones out who tie 
> method arguments into the base name of a function.  With no language changes, 
> it is possible to implement a pretty reasonable Python interop layer with the 
> call and member operations explicit, it looks like this:
> 
>   func example(foo : PyVal) -> PyVal {
> return  foo.get(member: “bar”).call(args: (“x”, 1), (“”, 23), (“y”, 
> 17))
>   }
> 
> and while it is totally possible to sugar common cases, e.g.:
> 
>   func example(foo : PyVal) -> PyVal {
> return  foo.call(member: “bar”, args: (“x”, 1), (“”, 23), (“y”, 17))
>   }
> 
> you still need to support the basic model because Python supports currying 
> and has global functions with keyword arguments.  FWIW, Perl follows a 
> similar model, but doesn’t have keyword arguments.

Sure, the language models are different, but they're also different languages 
with different idioms, and bridging one to the other IMO doesn't mean it's a 
good idea to port over all the idioms literally. Allowing:

> a = foo.bar
> return a(x: 1, 23, y: 17)

may provide some initial familiarity to someone fresh from Python, but it will 
delay their ability to transition to Swift's way of doing things and confuse 
them when their own Swift code they write doesn't work the Python way. We 
should be able to make the more Swift-idiomatic `a = foo.bar(x:y:); a(1, 23, 
17)` form work.
-Joe

> I don’t really care much about the implementation approach (if this proposal 
> isn’t the right one, fine!) but it is important to get this down to:
> 
>   func example(foo : PyVal) -> PyVal {
> return  foo.bar(x: 1, 23, y: 17)
>   }
> 
> which I hope you’ll agree is a *HUGE* readability and writability benefit, so 
> much so that users would reject the long hand notion.
> 
> 
> The discussion phase in the previous thread considered several approaches, 
> including burning python specific support in, implementing a python importer, 
> and implementing a single “dynamic thing” protocol.  These are all bad ideas 
> for reasons described in the thread.  If you’re curious, I’m happy to 
> elaborate in alternatives considered.
> 
> As such, discussion converged on pitching two proposals, which are generally 
> useful beyond this niche:
> 
> 1. The dynamically callable one already written.
> 2. A dynamically member lookupable proposal to sugar things like 
> foo.get(member: “bar”) - and the corresponding setter.
> 
> The former one is presumably useful for things outside dynamic languages, 
> e.g. implementing dynamic “proxy” type interfaces.
> The second one is useful for far more than just dynamic languages, e.g. 
> sugaring json keypath traversals.
> 
> 
> -Chris
> 
> 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Joe Groff via swift-evolution


> On Nov 11, 2017, at 10:12 AM, Chris Lattner  wrote:
> 
> On Nov 11, 2017, at 6:52 AM, Joe Groff via swift-evolution 
>  wrote:
 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.
>>> 
>>> I’m pretty sure it doesn’t, but good news: since Swift requires an 
>>> implementation before the proposal can be officially reviewed, you will be 
>>> able to look at the actual patch to make this decision.
>> 
>> And the goal of the pitch phase is to hopefully save you the tears of trying 
>> to implement something if it's a bad idea.
> 
> Appreciated.  Fortunately I enjoy coding so it’s not that big of a deal for 
> me.
> 
 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.
>>> 
>>> This is really gross.  The goal here is to make Python feel natural.  If 
>>> you oppose this proposal then we’ll have to find some other way to provide 
>>> an elegant experience:
 x∫(0, "foo", bar: "bas”)
>>> 
>>> This is not going to be acceptable to users.
>> 
>> Is it? My choice of operator character is silly, but it's the same amount of 
>> syntactic overhead as an optional chain/force call. It's a fair sight better 
>> than x.call(args: ..., keywordArgs: ...), I hope you'd agree, and is 
>> something that works without any language change.
> 
> Yes, I’m happy to explore that, and I agree this approach doesn’t require 
> language changes.  That said, there are three things you should understand:
> 
> 1) Details matter.  While you claim that there is some other operator 
> character that could be awesome, I’m not seeing it.  Can you try harder to 
> come up with something that you think would be acceptable?
> 
> 2) The point of the entire proposal is that a certain audience will be using 
> the feature enabled by this (python interop) *a lot*, so ergonomics matter.
> 
> 3) This feature (python interop) is aimed to get Python programmers to 
> convert to Swift, not simply to ease friction for existing Swift programmers 
> (most of whom are iOS developers, to whom this feature is completely 
> irrelevant).  Getting people to move from Python to Swift is a challenge, and 
> syntax does actually matter. I hope we can agree that expanding the community 
> of Swift developers is a laudable goal.  

Sure. I suggest it not as a final endpoint but as incremental progress you can 
make with the language today. If you can get some early adopters interested in 
moving from Python to Swift with some small warts now and the promise of 
refined syntax in the future, that could let you make progress while we work 
out the right final model for dynamic language interop. Since you have long 
term ambitions in this space, I think it'd pay off to consider more 
infrastructurally-heavy features with bigger long-term payoffs.
> 
>> You mentioned variadics as being inadequate for your purposes as a 
>> considered alternative, but a variadics model that wasn't based on type 
>> erasure to arrays and kept runtime type information about the argument tuple 
>> that was passed in, along with better reflection APIs for accessing that 
>> type info, might lead to something you can use by incrementally improving 
>> the expressivity of existing language features instead of adding new ones.
> 
> I’m not sure what you mean by this: variadics are fine. The hard part is 
> getting the keyword arguments for a call dynamically.  Can you point to what 
> you’re referring to in the proposal?

I was referring to your comment in this section:

> Statically checking for exact signatures
> 
> This proposal does not allow a type to specify an exact signature for the 
> callable - a specific number of parameters with specific types. If we went 
> down that route, the best approach would be to introduce a new declaration 
> kind (which would end up being very similar to get-only subscripts) since, in 
> general, a type could want multiple concrete callable signatures, and those 
> signatures should participate in overload resolution.
> 
> While such a feature could be interesting for some use cases, it is almost 
> entirely orthogonal from this proposal: it addresses different use cases and 
> does not solve the needs of this proposal. It does not address our needs 
> because even a variadic callable declaration would not provide access to the 
> keyword argument labels we need.
> 
We know our variadics model is inadequate in a lot of ways. I was suggesting 
there are ways of extending it that could allow the 

Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution


> On Nov 11, 2017, at 10:33 AM, Chris Lattner via swift-evolution 
>  wrote:
> 
> 
> The discussion phase in the previous thread considered several approaches, 
> including burning python specific support in, implementing a python importer, 
> and implementing a single “dynamic thing” protocol.  These are all bad ideas 
> for reasons described in the thread.  If you’re curious, I’m happy to 
> elaborate in alternatives considered.
> 
> As such, discussion converged on pitching two proposals, which are generally 
> useful beyond this niche:
> 
> 1. The dynamically callable one already written.
> 2. A dynamically member lookupable proposal to sugar things like 
> foo.get(member: “bar”) - and the corresponding setter.
> 

One other pertinent thing from the discussion thread: it seriously isn’t lost 
on me how the Swift type checker works.  One of the the alternate designs that 
I intend to explore is to add a second method to the protocol, to encapsulate 
the Swift member dispatch idiom:

  func dynamicCallMember(member: String, arguments: [(String, 
DynamicCallableArgument)]) throws ->
 DynamicCallableResult


This puts more effort onto the implementer of the protocol, but I think that is 
a totally acceptable tradeoff to save compiler complexity.

-Chris

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution
On Nov 11, 2017, at 10:35 AM, John Holdsworth  wrote:
> Integration with Xcode would be straightforward but it’s been Android Studio
> I’ve most experience with. For that it was just a case of adapting a gradle
> plugin to add a rebuild phase. If you can’t automate it running a generator
> when you change the surface of your api is not a big overhead.
> 
> Supporting playgrounds would involve being able to import a user module
> to publish the api and link with python. Is that possible?

Playgrounds do not have a build system if used outside the context of a larger 
app project.

-Chris


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread John Holdsworth via swift-evolution
Integration with Xcode would be straightforward but it’s been Android Studio
I’ve most experience with. For that it was just a case of adapting a gradle
plugin to add a rebuild phase. If you can’t automate it running a generator
when you change the surface of your api is not a big overhead.

Supporting playgrounds would involve being able to import a user module
to publish the api and link with python. Is that possible?

John

> On 11 Nov 2017, at 18:20, Chris Lattner  wrote:
> 
> 
> 
>> On Nov 11, 2017, at 9:53 AM, Joe Groff via swift-evolution 
>> > wrote:
>> 
>> 
>> 
>> On Nov 11, 2017, at 9:44 AM, John Holdsworth > > wrote:
>> 
>>> Isn’t there a third way? I wrote a bridge between Swift and Java without 
>>> having to
>>> change the compiler at all by using a code generator to generate bridging 
>>> Swift
>>> rather than having a Java importer.
>> 
>> Good point. For unidirectional importing without deep support for overriding 
>> or runtime integration like what we do with ObjC, which AIUI is the extent 
>> of Chris's ambition with Python interfacing here, a code generator can get 
>> the job done without requiring deep compiler integration, though at the 
>> expense of needing an added tool in your build process. Have you looked at 
>> all into making SwiftJava integrate with the package manager or with Xcode 
>> yet? How's that experience?
> 
> Also, what is the playground experience like?
> 
> -Chris
> 
> 

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution


> On Nov 11, 2017, at 10:15 AM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
> 
> On Nov 11, 2017, at 10:04 AM, Chris Lattner  > wrote:
> 
>> 
>> 
>>> On Nov 11, 2017, at 6:29 AM, Joe Groff via swift-evolution 
>>> > wrote:
>>> 
 below the fold as far as the rest of the language is concerned. You could 
 just as well written what the importer synths up in Swift directly:
 
 func foo(bar: String) {
 unsafeBitCast(objc_msgSend, to: @convention(c) (AnyObject, Selector, 
 NSString) -> ().self)(self, "fooWithBar:", NSString(bar))
 }
 
 and the rest of the language would be none the wiser.
>>> 
>>> Though, since you bring up objc_msgSend, the way it works in ObjC might be 
>>> a better fit for Swift's name lookup model, since their keyword argument 
>>> models are similar. If Swift had a 'method of last resort' like ObjC's
>> 
>> In fact, this is the subject of the next proposal that I will write up when 
>> I have time.
> 
> It seems to me like a dynamic method-of-last-resort feature would subsume 
> this proposal. Out of curiosity, why would we need both?

It seems that you missed the "[Discussion] Swift for Data Science / ML / Big 
Data analytics” thread, in which a lot of context was discussed, as well as 
multiple design approaches.  In any case, I will summarize here:

There are two fundamental operations that need to be supported to make a big 
impact on dynamic language interop: member lookup and calls.

Many languages treat these as separable concepts.  In Python for example, these 
are equivalent:

return foo.bar(x: 1, 23, y: 17)
and:
a = foo.bar
return a(x: 1, 23, y: 17)

Swift and the other Smalltalk inspired languages are the odd ones out who tie 
method arguments into the base name of a function.  With no language changes, 
it is possible to implement a pretty reasonable Python interop layer with the 
call and member operations explicit, it looks like this:

func example(foo : PyVal) -> PyVal {
  return  foo.get(member: “bar”).call(args: (“x”, 1), (“”, 23), (“y”, 
17))
}

and while it is totally possible to sugar common cases, e.g.:

func example(foo : PyVal) -> PyVal {
  return  foo.call(member: “bar”, args: (“x”, 1), (“”, 23), (“y”, 17))
}

you still need to support the basic model because Python supports currying and 
has global functions with keyword arguments.  FWIW, Perl follows a similar 
model, but doesn’t have keyword arguments.

I don’t really care much about the implementation approach (if this proposal 
isn’t the right one, fine!) but it is important to get this down to:

func example(foo : PyVal) -> PyVal {
  return  foo.bar(x: 1, 23, y: 17)
}

which I hope you’ll agree is a *HUGE* readability and writability benefit, so 
much so that users would reject the long hand notion.


The discussion phase in the previous thread considered several approaches, 
including burning python specific support in, implementing a python importer, 
and implementing a single “dynamic thing” protocol.  These are all bad ideas 
for reasons described in the thread.  If you’re curious, I’m happy to elaborate 
in alternatives considered.

As such, discussion converged on pitching two proposals, which are generally 
useful beyond this niche:

1. The dynamically callable one already written.
2. A dynamically member lookupable proposal to sugar things like 
foo.get(member: “bar”) - and the corresponding setter.

The former one is presumably useful for things outside dynamic languages, e.g. 
implementing dynamic “proxy” type interfaces.
The second one is useful for far more than just dynamic languages, e.g. 
sugaring json keypath traversals.


-Chris



___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-dev] Re-pitch: Deriving collections of enum cases

2017-11-11 Thread Xiaodi Wu via swift-evolution
On Sat, Nov 11, 2017 at 11:23 AM, Tony Allevato 
wrote:

>
>
> On Fri, Nov 10, 2017 at 11:01 PM Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> On Sat, Nov 11, 2017 at 12:15 AM, Brent Royal-Gordon via swift-evolution
>>  wrote:
>>
>>> > Personally I like the flexibility provided by the associatedtype, but
>>> I also recognize it won't be incredibly useful for enums — more so if we
>>> wanted to provide e.g. UInt8.allValues, whose ideal implementation might be
>>> "return 0...UInt8.max". So I could see allowing allValues to be any
>>> sequence or collection, but flexibility for allCases might be less
>>> important. Others should weigh in here.
>>>
>>>
>>> I think we should allow any `Collection` (option 3), and I think we
>>> should have a `DefaultCaseCollection` type in the standard library
>>> which encapsulates the interaction with the runtime.
>>>
>>> A `Collection` is good because `Sequence` doesn't provide all of the
>>> guarantees we want—`allValues` should never be single-pass and it should
>>> always be possible to resume iteration at an earlier point, which
>>> `Sequence` doesn't guarantee. (It probably makes sense to use
>>> `BidirectionalCollection`, actually; I'm less sure about
>>> `RandomAccessCollection`.) At the same time, an `Array` ties us to all
>>> sorts of things that are unnecessary at best and harmful at worst, like a
>>> heap allocation. It also forces us into integer indices, which may be
>>> suboptimal for certain use cases (particularly if we later want to support
>>> associated values). And it prevents us from making types like integers
>>> conform, which I think would be a good idea.
>>>
>>> Meanwhile, encapsulating the runtime machinery in
>>> `DefaultCaseCollection` gives users an escape hatch: If the enum you want
>>> to use doesn't conform to `ValueEnumerable`, but you're certain it's
>>> compatible, you can construct a `DefaultCaseCollection` for it.
>>> `DefaultCaseCollection` can be a `RandomAccessCollection` with `Int`
>>> indices, making it convenient to use, but at the same time, it's *not* an
>>> array, so it doesn't have to allocate storage or think about `NSArray`
>>> bridging. And it minimizes the complexity of what the compiler needs to
>>> synthesize.
>>>
>>> public protocol ValueEnumerable {
>>> associatedtype AllValues: BidirectionalCollection where
>>> AllValues.Element == Self
>>> static var allValues: AllValues { get }
>>> }
>>>
>>> // The compiler automatically does `typealias AllValues =
>>> DefaultCaseCollection` if the
>>> // conformance is on the original declaration, the type is
>>> compatible (e.g. no associated values),
>>> // and a different type is neither explicitly specified nor
>>> inferred. That will cause this default
>>> // implementation to be used:
>>> extension ValueEnumerable where AllValues ==
>>> DefaultCaseCollection {
>>> public static var allValues: DefaultCaseCollection
>>> {
>>> return DefaultCaseCollection(unsafeForEnum:
>>> Self.self)
>>> }
>>> }
>>>
>>> public struct DefaultCaseCollection:
>>> RandomAccessCollection {
>>> public var startIndex: Int { return 0 }
>>> public let endIndex: Int
>>>
>>> public init(unsafeForEnum _: Enum.Type) {
>>> endIndex = _countCaseValues(Enum.self)
>>> }
>>>
>>> public subscript(i: Int) -> Enum {
>>> precondition(indices.contains(i), "Case index
>>> out of range")
>>> return Builtin.reinterpretCast(i) as Enum
>>> }
>>> }
>>>
>>
>> Nit: if you want to call it `ValueEnumerable`, then this should be
>> `DefaultValueCollection`.
>>
>> More generally though, I can see the appeal of allowing `Int` to conform
>> to `ValueEnumerable`, but I've got a feeling that this is headed rapidly in
>> the direction of overengineering a feature without a good rationale for the
>> additional complexity. The stated use case is to enumerate the cases of an
>> enum, and any additional complexity above that should stand on its own
>> merit. I disagree quite vehemently that protocols should be "as general as
>> possible"; rather, they exist to enable useful generic algorithms and
>> should be as _useful_ as possible. There is a happy medium beyond which
>> overengineering the design makes a protocol markedly less
>> usable/approachable for the sake of enabling rare functionality.
>>
>
> Perhaps "no more specific than they need to be" would have been a better
> choice of words on my part than "as general as possible".
>
> I'm not sure why you think this decision makes the protocol "markedly less
> usable/approachable". and I think you're seeing a lot of complexity that
> isn't there. Regarding good rationale, I've 

Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution


> On Nov 11, 2017, at 9:53 AM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
> 
> On Nov 11, 2017, at 9:44 AM, John Holdsworth  > wrote:
> 
>> Isn’t there a third way? I wrote a bridge between Swift and Java without 
>> having to
>> change the compiler at all by using a code generator to generate bridging 
>> Swift
>> rather than having a Java importer.
> 
> Good point. For unidirectional importing without deep support for overriding 
> or runtime integration like what we do with ObjC, which AIUI is the extent of 
> Chris's ambition with Python interfacing here, a code generator can get the 
> job done without requiring deep compiler integration, though at the expense 
> of needing an added tool in your build process. Have you looked at all into 
> making SwiftJava integrate with the package manager or with Xcode yet? How's 
> that experience?

Also, what is the playground experience like?

-Chris


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution


> On Nov 11, 2017, at 7:02 AM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
> 
> On Nov 10, 2017, at 8:35 PM, Chris Lattner via swift-evolution 
> > wrote:
> 
>> 
>>> On Nov 10, 2017, at 6:12 PM, Slava Pestov via swift-evolution 
>>> > wrote:
>>> 
>>> 
>>> 
 On Nov 10, 2017, at 6:10 PM, Matthew Johnson via swift-evolution 
 > wrote:
 
 Setting this aside, I’m very curious to hear whether type providers 
 influence your thinking after you’ve had a chance to look into them.  I 
 have always thought they were very cool.
>>> 
>>> I’m in favor of solving this problem with something like type providers 
>>> also. The required compiler changes would be significant but would also 
>>> clean up the interface between the ClangImporter, Sema and Serialization. 
>>> If done right it would be a net gain that would benefit all users, instead 
>>> of just adding YetAnotherCornerCase™ that makes implementation maintainers 
>>> curse and scream.
>> 
>> I find it ironic that you’re talking pejoratively about a feature that has 
>> very narrow impact, complaining about how much of an impact on the compiler 
>> it would have, and then pine for a hugely invasive feature - one that would 
>> cause a ton of code churn, and probably wouldn’t actually be enough to 
>> eliminate the special cases in place because of ObjC interop.
> 
> You underestimate the impact this would have on function call type checking, 
> but since this is an additive, non-ABI-stability feature, I have trouble 
> considering it a candidate for Swift 5,

The guidelines for Swift 5 are publicly documented here:
https://github.com/apple/swift-evolution/blob/master/README.md#evolution-process-for-swift-5
 


This is relevant and seems reasonable to me:
Syntactic additions. Syntactic changes do not increase the expressive power of 
the language but do increase its complexity. Consequently, such changes must be 
extremely well-motivated and will be subject to additional scrutiny. We will 
expect proposals to include concrete data about how wide spread the positive 
impact will be.


I explicitly point out that this is a sugar change.

> so I don't think there's a time constraint forcing us to consider the 
> "narrow" vs "huge" dimension. What's the best thing for the language and 
> tools in the long term? This is a feature that influences the semantics of 
> potentially any call site in all Swift code, which we'd have to live with 
> forever if we accepted it now. Opening up the compiler architecture to make 
> custom importers easier to write is a great solution to a ton of problems, 
> including yours I think, without adding complexity to the core language. 
> Experience in .NET land seems to show it's a great technique for integrating 
> dynamic systems with static type systems, without poking unnecessary holes in 
> the static language's type system

As I mentioned, I’m not familiar with F# type providers.  As I told you 
upthread, I will read about them and respond with an informed opinion when I 
have time.

-Chris


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Joe Groff via swift-evolution


> On Nov 11, 2017, at 10:04 AM, Chris Lattner  wrote:
> 
> 
> 
>>> On Nov 11, 2017, at 6:29 AM, Joe Groff via swift-evolution 
>>>  wrote:
>>> 
>>> below the fold as far as the rest of the language is concerned. You could 
>>> just as well written what the importer synths up in Swift directly:
>>> 
>>> func foo(bar: String) {
>>> unsafeBitCast(objc_msgSend, to: @convention(c) (AnyObject, Selector, 
>>> NSString) -> ().self)(self, "fooWithBar:", NSString(bar))
>>> }
>>> 
>>> and the rest of the language would be none the wiser.
>> 
>> Though, since you bring up objc_msgSend, the way it works in ObjC might be a 
>> better fit for Swift's name lookup model, since their keyword argument 
>> models are similar. If Swift had a 'method of last resort' like ObjC's
> 
> In fact, this is the subject of the next proposal that I will write up when I 
> have time.

It seems to me like a dynamic method-of-last-resort feature would subsume this 
proposal. Out of curiosity, why would we need both?

-Joe
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution
On Nov 11, 2017, at 6:52 AM, Joe Groff via swift-evolution 
 wrote:
>>> 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.
>> 
>> I’m pretty sure it doesn’t, but good news: since Swift requires an 
>> implementation before the proposal can be officially reviewed, you will be 
>> able to look at the actual patch to make this decision.
> 
> And the goal of the pitch phase is to hopefully save you the tears of trying 
> to implement something if it's a bad idea.

Appreciated.  Fortunately I enjoy coding so it’s not that big of a deal for me.

>>> 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.
>> 
>> This is really gross.  The goal here is to make Python feel natural.  If you 
>> oppose this proposal then we’ll have to find some other way to provide an 
>> elegant experience:
>>> x∫(0, "foo", bar: "bas”)
>> 
>> This is not going to be acceptable to users.
> 
> Is it? My choice of operator character is silly, but it's the same amount of 
> syntactic overhead as an optional chain/force call. It's a fair sight better 
> than x.call(args: ..., keywordArgs: ...), I hope you'd agree, and is 
> something that works without any language change.

Yes, I’m happy to explore that, and I agree this approach doesn’t require 
language changes.  That said, there are three things you should understand:

1) Details matter.  While you claim that there is some other operator character 
that could be awesome, I’m not seeing it.  Can you try harder to come up with 
something that you think would be acceptable?

2) The point of the entire proposal is that a certain audience will be using 
the feature enabled by this (python interop) *a lot*, so ergonomics matter.

3) This feature (python interop) is aimed to get Python programmers to convert 
to Swift, not simply to ease friction for existing Swift programmers (most of 
whom are iOS developers, to whom this feature is completely irrelevant).  
Getting people to move from Python to Swift is a challenge, and syntax does 
actually matter. I hope we can agree that expanding the community of Swift 
developers is a laudable goal.  

> You mentioned variadics as being inadequate for your purposes as a considered 
> alternative, but a variadics model that wasn't based on type erasure to 
> arrays and kept runtime type information about the argument tuple that was 
> passed in, along with better reflection APIs for accessing that type info, 
> might lead to something you can use by incrementally improving the 
> expressivity of existing language features instead of adding new ones.

I’m not sure what you mean by this: variadics are fine. The hard part is 
getting the keyword arguments for a call dynamically.  Can you point to what 
you’re referring to in the proposal?

-Chris

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution


> On Nov 11, 2017, at 6:29 AM, Joe Groff via swift-evolution 
>  wrote:
> 
>> below the fold as far as the rest of the language is concerned. You could 
>> just as well written what the importer synths up in Swift directly:
>> 
>> func foo(bar: String) {
>> unsafeBitCast(objc_msgSend, to: @convention(c) (AnyObject, Selector, 
>> NSString) -> ().self)(self, "fooWithBar:", NSString(bar))
>> }
>> 
>> and the rest of the language would be none the wiser.
> 
> Though, since you bring up objc_msgSend, the way it works in ObjC might be a 
> better fit for Swift's name lookup model, since their keyword argument models 
> are similar. If Swift had a 'method of last resort' like ObjC's

In fact, this is the subject of the next proposal that I will write up when I 
have time.

-Chris

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution


> On Nov 11, 2017, at 2:19 AM, Tino Heth via swift-evolution 
>  wrote:
> 
>> Example Usage
>> 
> 
> Swift is quite flexible on what can act as a closure — would it be allowed to 
> use a dynamic callable in that context?
> I guess forwarding of
> 
> let closure: ([(String, Int)]) -> Int  = DynamicCallableType()
> 
> to the dynamicCall method of DynamicCallableType isn’t that hard, but 
> wouldn’t it be odd if the value of closure changes when you leave out its 
> type?

I’m not sure I understand what you’re getting at.  Can you show how this would 
work with the example in the motivation section?

-Chris


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution
On Nov 11, 2017, at 2:04 AM, Tino Heth via swift-evolution 
 wrote:
> I generally dislike „protocol magic“, but I think in this case, there is also 
> a precedence for an (imho) better way:
> There’s no „Subscriptable“ protocol, and I would prefer callable types to be 
> handled in the same way (afaics, subscripts are already used as „callable 
> with different braces“ today in some cases).
> 
> You mention subscripts in „Alternatives considered“, but without an 
> explanation why you don’t want a new declaration kind for dynamicCall — and I 
> think it could co-exist with the orthogonal use case that you mention.

Sure, this is a great question.  We could definitely introduce a new 
declaration kind.  The tradeoff I see is that that is far more language 
invasive, and that none of our existing decls work this way: packaging up 
syntax (keyword labels) and handing it off.

One theoretical way to address this is to introduce a macro system, but that 
would be far more invasive and isn’t going to happen now (and perhaps never?).

Despite the claims, the impact of this proposal on the compiler is extremely 
narrow.

-Chris

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] async void

2017-11-11 Thread Adam Kemp via swift-evolution


> On Nov 11, 2017, at 6:24 AM, Yuta Koshizawa  wrote:
> 
> If you replace `async` with `throws`, you can get answers.
> 
> 
>> Can you declare an async closure variable?
> 
> Yes. Like `let throwingClosure:() throws -> Void = { ... }`.
> 
> 
>> Can a non-async closure be passed to a function expecting a async closure?
> 
> Yes. Like we can pass `() -> Void` to a function expecting a throwing
> closure `() throws -> Void`.
> 
> It is possible because `(Foo) throws -> Bar` is a supertype of `(Foo)
> -> Bar`. `(Foo) async -> Bar` is a supertype of `(Foo) -> Bar` in the
> same way.
> 
> To treat an async function as a sync function is legal. It is similar
> to make a `Promise` by `Promise(value)` which is completed
> immediately.
> 
> 
>> Can an async closure be passed to a function expecting a non-async closure?
> 
> No. `() -> Void` is a subtype of `() async -> Void`. It is same as
> passing `() throws -> Void` to a function expecting `() -> Void` is
> not allowed.

But why not? Just asserting that it must work the same as throws is not a 
convincing argument. You have to justify why it must work that way. I think 
there is good reason to allow it, which I have described. What reason is there 
to disallow it?

>> It’s weird to me that we would allow you to have async void closures but not 
>> async void functions
> 
> I am not sure what you mean. "async void closures" and "async void
> functions" have a same type. Following two are almost same.
> 
> ```
> func foo() async -> Void { ... }
> let foo: () async -> Void = { ... }
> ```

What started this thread is my suggestion that you should be able to write an 
async void function. The current proposal doesn’t allow that. That’s why you 
have to use beginAsync.

I don’t think that makes sense. It sounds like you also think that would be 
strange, hence your assumption that you could.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Joe Groff via swift-evolution


> On Nov 11, 2017, at 9:44 AM, John Holdsworth  wrote:
> 
> Isn’t there a third way? I wrote a bridge between Swift and Java without 
> having to
> change the compiler at all by using a code generator to generate bridging 
> Swift
> rather than having a Java importer.

Good point. For unidirectional importing without deep support for overriding or 
runtime integration like what we do with ObjC, which AIUI is the extent of 
Chris's ambition with Python interfacing here, a code generator can get the job 
done without requiring deep compiler integration, though at the expense of 
needing an added tool in your build process. Have you looked at all into making 
SwiftJava integrate with the package manager or with Xcode yet? How's that 
experience?

-Joe

> The script introspects the classes/packages
> you’re interested in using a script and generates code such as the following:
> 
> /// public java.lang.String java.lang.Object.toString()
> 
> private static var toString_MethodID_9: jmethodID?
> 
> open func toString() -> String! {
> var __locals = [jobject]()
> var __args = [jvalue]( repeating: jvalue(), count: 1 )
> let __return = JNIMethod.CallObjectMethod( object: javaObject, 
> methodName: "toString", methodSig: "()Ljava/lang/String;", methodCache: 
> _MethodID_9, args: &__args, locals: &__locals )
> defer { JNI.DeleteLocalRef( __return ) }
> return __return != nil ? String( javaObject: __return ) : nil
> }
> 
> This bridging code, along with some supporting classes is compiled 
> conventionally
> along with your app. See:
> 
> https://github.com/SwiftJava/SwiftJava
> https://github.com/SwiftJava/java_swift/blob/master/Sources/JavaObject.swift
> https://github.com/SwiftJava/SwiftJava/blob/master/src/genswift.java
> 
> Python’s introspection seems to be reasonably capable and could certainly 
> support
> this approach. You’d need some sort of omni-type enum for the arguments and 
> return.
> 
> https://stackoverflow.com/questions/196960/can-you-list-the-keyword-arguments-a-python-function-receives
> https://docs.python.org/2/c-api/intro.html
> 
> John
> 
>> On 11 Nov 2017, at 16:13, David Hart via swift-evolution 
>>  wrote:
>> 
>> 
>> On 11 Nov 2017, at 16:02, Joe Groff via swift-evolution 
>>  wrote:
>> 
>>> 
>>> 
 On Nov 10, 2017, at 8:35 PM, Chris Lattner via swift-evolution 
  wrote:
 
 
>> On Nov 10, 2017, at 6:12 PM, Slava Pestov via swift-evolution 
>>  wrote:
>> 
>> 
>> 
>> On Nov 10, 2017, at 6:10 PM, Matthew Johnson via swift-evolution 
>>  wrote:
>> 
>> Setting this aside, I’m very curious to hear whether type providers 
>> influence your thinking after you’ve had a chance to look into them.  I 
>> have always thought they were very cool.
> 
> I’m in favor of solving this problem with something like type providers 
> also. The required compiler changes would be significant but would also 
> clean up the interface between the ClangImporter, Sema and Serialization. 
> If done right it would be a net gain that would benefit all users, 
> instead of just adding YetAnotherCornerCase™ that makes implementation 
> maintainers curse and scream.
 
 I find it ironic that you’re talking pejoratively about a feature that has 
 very narrow impact, complaining about how much of an impact on the 
 compiler it would have, and then pine for a hugely invasive feature - one 
 that would cause a ton of code churn, and probably wouldn’t actually be 
 enough to eliminate the special cases in place because of ObjC interop.
>>> 
>>> You underestimate the impact this would have on function call type 
>>> checking, but since this is an additive, non-ABI-stability feature, I have 
>>> trouble considering it a candidate for Swift 5, so I don't think there's a 
>>> time constraint forcing us to consider the "narrow" vs "huge" dimension. 
>>> What's the best thing for the language and tools in the long term? This is 
>>> a feature that influences the semantics of potentially any call site in all 
>>> Swift code, which we'd have to live with forever if we accepted it now. 
>>> Opening up the compiler architecture to make custom importers easier to 
>>> write is a great solution to a ton of problems, including yours I think, 
>>> without adding complexity to the core language. Experience in .NET land 
>>> seems to show it's a great technique for integrating dynamic systems with 
>>> static type systems, without poking unnecessary holes in the static 
>>> language's type system
>> 
>> I agree with Joe. I also think that it would be very important to compare 
>> both approaches in detail before choosing one, because the last thing we 
>> want is to end up with both in the language. And if this proposal is 

Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread John Holdsworth via swift-evolution
Isn’t there a third way? I wrote a bridge between Swift and Java without having 
to
change the compiler at all by using a code generator to generate bridging Swift
rather than having a Java importer. The script introspects the classes/packages
you’re interested in using a script and generates code such as the following:

/// public java.lang.String java.lang.Object.toString()

private static var toString_MethodID_9: jmethodID?

open func toString() -> String! {
var __locals = [jobject]()
var __args = [jvalue]( repeating: jvalue(), count: 1 )
let __return = JNIMethod.CallObjectMethod( object: javaObject, 
methodName: "toString", methodSig: "()Ljava/lang/String;", methodCache: 
_MethodID_9, args: &__args, locals: &__locals )
defer { JNI.DeleteLocalRef( __return ) }
return __return != nil ? String( javaObject: __return ) : nil
}

This bridging code, along with some supporting classes is compiled 
conventionally
along with your app. See:

https://github.com/SwiftJava/SwiftJava 
https://github.com/SwiftJava/java_swift/blob/master/Sources/JavaObject.swift 

https://github.com/SwiftJava/SwiftJava/blob/master/src/genswift.java 


Python’s introspection seems to be reasonably capable and could certainly 
support
this approach. You’d need some sort of omni-type enum for the arguments and 
return.

https://stackoverflow.com/questions/196960/can-you-list-the-keyword-arguments-a-python-function-receives
 

https://docs.python.org/2/c-api/intro.html 


John

> On 11 Nov 2017, at 16:13, David Hart via swift-evolution 
>  wrote:
> 
> 
> On 11 Nov 2017, at 16:02, Joe Groff via swift-evolution 
> > wrote:
> 
>> 
>> 
>> On Nov 10, 2017, at 8:35 PM, Chris Lattner via swift-evolution 
>> > wrote:
>> 
>>> 
 On Nov 10, 2017, at 6:12 PM, Slava Pestov via swift-evolution 
 > wrote:
 
 
 
> On Nov 10, 2017, at 6:10 PM, Matthew Johnson via swift-evolution 
> > wrote:
> 
> Setting this aside, I’m very curious to hear whether type providers 
> influence your thinking after you’ve had a chance to look into them.  I 
> have always thought they were very cool.
 
 I’m in favor of solving this problem with something like type providers 
 also. The required compiler changes would be significant but would also 
 clean up the interface between the ClangImporter, Sema and Serialization. 
 If done right it would be a net gain that would benefit all users, instead 
 of just adding YetAnotherCornerCase™ that makes implementation maintainers 
 curse and scream.
>>> 
>>> I find it ironic that you’re talking pejoratively about a feature that has 
>>> very narrow impact, complaining about how much of an impact on the compiler 
>>> it would have, and then pine for a hugely invasive feature - one that would 
>>> cause a ton of code churn, and probably wouldn’t actually be enough to 
>>> eliminate the special cases in place because of ObjC interop.
>> 
>> You underestimate the impact this would have on function call type checking, 
>> but since this is an additive, non-ABI-stability feature, I have trouble 
>> considering it a candidate for Swift 5, so I don't think there's a time 
>> constraint forcing us to consider the "narrow" vs "huge" dimension. What's 
>> the best thing for the language and tools in the long term? This is a 
>> feature that influences the semantics of potentially any call site in all 
>> Swift code, which we'd have to live with forever if we accepted it now. 
>> Opening up the compiler architecture to make custom importers easier to 
>> write is a great solution to a ton of problems, including yours I think, 
>> without adding complexity to the core language. Experience in .NET land 
>> seems to show it's a great technique for integrating dynamic systems with 
>> static type systems, without poking unnecessary holes in the static 
>> language's type system
> 
> I agree with Joe. I also think that it would be very important to compare 
> both approaches in detail before choosing one, because the last thing we want 
> is to end up with both in the language. And if this proposal is accepted, we 
> might refrain from introducing custom importers later, even if they are the 
> better long term solution.
> 
> I want Swift to continue to shine for a very long time because I enjoy 

Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Goffredo Marocchi via swift-evolution
Very interesting indeed...

class VehicleUtilities {

int numberOfAxles(Vehicle v) { return 2;} // a plausible default

int numberOfAxles (Truck t){ return 3;}

}




Vehicle v = new Truck();

VehicleUtilities u = new VehicleUtilities();

u.numberOfAxles(v); // returns 2


--> this is a nice concise example of even simple code can suffer from a
nasty code issue such as this...

On Sat, Nov 11, 2017 at 4:32 PM, Gwendal Roué via swift-evolution <
swift-evolution@swift.org> wrote:

>
> Le 11 nov. 2017 à 16:48, Joe Groff via swift-evolution <
> swift-evolution@swift.org> a écrit :
>
> That'd be great, but Swift violates Gilad Bracha's golden rule by having
> static overloading, and throws bidirectional type inference on top, so our
> static name resolution can't be treated as a specialization of a dynamic
> name lookup mechanism in all cases.
>
>
> I didn't know of Gilad Bracha, so you made me curious.
>
> I guess that the "golden rule" you refer to is here, for anyone curious:
> https://gbracha.blogspot.fr/2009/09/systemic-overload.html
>
> Gwendal Roué
>
>
> ___
> 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


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Chris Lattner via swift-evolution
On Nov 10, 2017, at 6:10 PM, Matthew Johnson via swift-evolution 
 wrote:
>>> On Nov 10, 2017, at 11:25 AM, Matthew Johnson via swift-evolution 
>>> > wrote:
>>> 
> 
> People have reasonably asked for the ability to make their own 
> function-like types in the past, such that "myvalue(...)" behaves like 
> sugar for "myvalue.call(...)" or something like that. In most cases, they 
> still want to have type system control over what arguments and results 
> their call operation produces. They don't really get that with this 
> proposal; they lose all control over the arity and argument types. 
 
 As I mentioned, this is directly addressed in the writeup. Here’s the link:
 https://gist.github.com/lattner/a6257f425f55fe39fd6ac7a2354d693d#staticly-checking-for-exact-signatures
  
 
>>> That discusses why you didn’t include it in the present proposal but I 
>>> think it’s reasonable to oppose adding a dynamic callable feature prior to 
>>> a more Swifty static callable.
>> 
>> Why?  One does not preclude the other.
> 
> For exactly the reason Joe articulates.  Some people will use what the 
> language offers to get the syntax they desire even if it sacrifices type 
> safety.  If we’re going to have first-class callable types in Swift (I think 
> it’s a great idea) type safety for native code should be prioritized over 
> syntactic convenience for dynamic language interop.  We can have both, but 
> the former should come first IMO.

Hi Matthew,

In point of fact, Swift already has the feature you are referring to.  It just 
spells it with square brackets instead of parentheses.  A simple change to the 
punctuation character has much less point than the proposal that I’m pitching.

-Chris


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [swift-dev] Re-pitch: Deriving collections of enum cases

2017-11-11 Thread Tony Allevato via swift-evolution
On Fri, Nov 10, 2017 at 11:01 PM Xiaodi Wu via swift-evolution <
swift-evolution@swift.org> wrote:

> On Sat, Nov 11, 2017 at 12:15 AM, Brent Royal-Gordon via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> > Personally I like the flexibility provided by the associatedtype, but I
>> also recognize it won't be incredibly useful for enums — more so if we
>> wanted to provide e.g. UInt8.allValues, whose ideal implementation might be
>> "return 0...UInt8.max". So I could see allowing allValues to be any
>> sequence or collection, but flexibility for allCases might be less
>> important. Others should weigh in here.
>>
>>
>> I think we should allow any `Collection` (option 3), and I think we
>> should have a `DefaultCaseCollection` type in the standard library
>> which encapsulates the interaction with the runtime.
>>
>> A `Collection` is good because `Sequence` doesn't provide all of the
>> guarantees we want—`allValues` should never be single-pass and it should
>> always be possible to resume iteration at an earlier point, which
>> `Sequence` doesn't guarantee. (It probably makes sense to use
>> `BidirectionalCollection`, actually; I'm less sure about
>> `RandomAccessCollection`.) At the same time, an `Array` ties us to all
>> sorts of things that are unnecessary at best and harmful at worst, like a
>> heap allocation. It also forces us into integer indices, which may be
>> suboptimal for certain use cases (particularly if we later want to support
>> associated values). And it prevents us from making types like integers
>> conform, which I think would be a good idea.
>>
>> Meanwhile, encapsulating the runtime machinery in `DefaultCaseCollection`
>> gives users an escape hatch: If the enum you want to use doesn't conform to
>> `ValueEnumerable`, but you're certain it's compatible, you can construct a
>> `DefaultCaseCollection` for it. `DefaultCaseCollection` can be a
>> `RandomAccessCollection` with `Int` indices, making it convenient to use,
>> but at the same time, it's *not* an array, so it doesn't have to allocate
>> storage or think about `NSArray` bridging. And it minimizes the complexity
>> of what the compiler needs to synthesize.
>>
>> public protocol ValueEnumerable {
>> associatedtype AllValues: BidirectionalCollection where
>> AllValues.Element == Self
>> static var allValues: AllValues { get }
>> }
>>
>> // The compiler automatically does `typealias AllValues =
>> DefaultCaseCollection` if the
>> // conformance is on the original declaration, the type is
>> compatible (e.g. no associated values),
>> // and a different type is neither explicitly specified nor
>> inferred. That will cause this default
>> // implementation to be used:
>> extension ValueEnumerable where AllValues ==
>> DefaultCaseCollection {
>> public static var allValues: DefaultCaseCollection {
>> return DefaultCaseCollection(unsafeForEnum:
>> Self.self)
>> }
>> }
>>
>> public struct DefaultCaseCollection: RandomAccessCollection
>> {
>> public var startIndex: Int { return 0 }
>> public let endIndex: Int
>>
>> public init(unsafeForEnum _: Enum.Type) {
>> endIndex = _countCaseValues(Enum.self)
>> }
>>
>> public subscript(i: Int) -> Enum {
>> precondition(indices.contains(i), "Case index out
>> of range")
>> return Builtin.reinterpretCast(i) as Enum
>> }
>> }
>>
>
> Nit: if you want to call it `ValueEnumerable`, then this should be
> `DefaultValueCollection`.
>
> More generally though, I can see the appeal of allowing `Int` to conform
> to `ValueEnumerable`, but I've got a feeling that this is headed rapidly in
> the direction of overengineering a feature without a good rationale for the
> additional complexity. The stated use case is to enumerate the cases of an
> enum, and any additional complexity above that should stand on its own
> merit. I disagree quite vehemently that protocols should be "as general as
> possible"; rather, they exist to enable useful generic algorithms and
> should be as _useful_ as possible. There is a happy medium beyond which
> overengineering the design makes a protocol markedly less
> usable/approachable for the sake of enabling rare functionality.
>

Perhaps "no more specific than they need to be" would have been a better
choice of words on my part than "as general as possible".

I'm not sure why you think this decision makes the protocol "markedly less
usable/approachable". and I think you're seeing a lot of complexity that
isn't there. Regarding good rationale, I've given that in this thread above
and in the previous discussion thread, but I'll summarize it again here:

1) "The stated use case is to enumerate the cases of an enum" isn't
sufficient for designing 

Re: [swift-evolution] [Review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-11 Thread Michel Fortin via swift-evolution
>   • What is your evaluation of the proposal?

One thing to keep in mind is that flatMap is basically the equivalent of 
optional chaining for non-`self` parameters.

let result = character?.hexValue // optional chaining
let result = character.flatMap { hexValue($0) } // optional "calling"?

I always found that `flatMap` was a weird name for this. Moreover, if the 
function you call is not returning an optional, `map` and `flatMap` essentially 
become synonyms. And thus I find myself using `flatMap` all the time when 
writing code like this, even when `map` would be enough, simply because it does 
what I expect all the time (like optional chaining, and unlike `map` that will 
instead pile up two layers of optionals).

The name `filterMap` makes a lot of sense for arrays, but it's still a bit 
awkward for optionals. I think the reason is that the most common thing you'd 
want to do with an optional is what `flatMap`/`filterMap` does, but the less 
specialized name (`map`) is already reserved with slightly different semantics. 
That is a bit dissonant in usage, even though the semantics makes sense in 
theory.

I think the most common use case, the one that mirrors optional chaining, 
should use the simplest name. I'm not sure what that word would be though.

[[
Side note: If only there was a nice way to express optional calling (when one 
of the parameters needs to be unwrapped or the call is skipped) like there is 
for optional chaining... I dream of this:

let result = optional hexValue(character?)

where `optional` before an expression enables explicit unwrapping in 
subexpressions with `?` and any failure to unwrap a subexpression causes the 
optional expression to return `nil`. But that might be asking for too much 
sugar.
]]


>   • Is the problem being addressed significant enough to warrant a change 
> to Swift?

I actually implemented `Sequence.filterMap` and `Optional.filterMap` in one of 
my projects and attempted to replace every `flatMap` with it. Looks like most 
of the `flatMap` calls in my project are used to filter optionals in arrays or 
doing optional calling. Only a tiny amount had to keep using `flatMap` because 
they were flattening nested arrays. That leads me to the conclusion that a 
better name would make most of the code more readable.

I think the change is worth it for arrays. Flattening an array is not the same 
thing as removing parts of it, so the word "filter" adds clarity.

I'm not sure it adds any clarity for optionals though.


>   • Does this proposal fit well with the feel and direction of Swift?

I think it fits well for arrays. Not sure about optionals.


>   • If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?

N/A


>   • How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?

I implemented filterMap to see what it'd feel like.


-- 
Michel Fortin
https://michelf.ca

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Gwendal Roué via swift-evolution

> Le 11 nov. 2017 à 16:48, Joe Groff via swift-evolution 
>  a écrit :
> 
> That'd be great, but Swift violates Gilad Bracha's golden rule by having 
> static overloading, and throws bidirectional type inference on top, so our 
> static name resolution can't be treated as a specialization of a dynamic name 
> lookup mechanism in all cases.

I didn't know of Gilad Bracha, so you made me curious. 

I guess that the "golden rule" you refer to is here, for anyone curious: 
https://gbracha.blogspot.fr/2009/09/systemic-overload.html 


Gwendal Roué

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread David Hart via swift-evolution

> On 11 Nov 2017, at 16:02, Joe Groff via swift-evolution 
>  wrote:
> 
> 
> 
>> On Nov 10, 2017, at 8:35 PM, Chris Lattner via swift-evolution 
>>  wrote:
>> 
>> 
>>> On Nov 10, 2017, at 6:12 PM, Slava Pestov via swift-evolution 
>>>  wrote:
>>> 
>>> 
>>> 
 On Nov 10, 2017, at 6:10 PM, Matthew Johnson via swift-evolution 
  wrote:
 
 Setting this aside, I’m very curious to hear whether type providers 
 influence your thinking after you’ve had a chance to look into them.  I 
 have always thought they were very cool.
>>> 
>>> I’m in favor of solving this problem with something like type providers 
>>> also. The required compiler changes would be significant but would also 
>>> clean up the interface between the ClangImporter, Sema and Serialization. 
>>> If done right it would be a net gain that would benefit all users, instead 
>>> of just adding YetAnotherCornerCase™ that makes implementation maintainers 
>>> curse and scream.
>> 
>> I find it ironic that you’re talking pejoratively about a feature that has 
>> very narrow impact, complaining about how much of an impact on the compiler 
>> it would have, and then pine for a hugely invasive feature - one that would 
>> cause a ton of code churn, and probably wouldn’t actually be enough to 
>> eliminate the special cases in place because of ObjC interop.
> 
> You underestimate the impact this would have on function call type checking, 
> but since this is an additive, non-ABI-stability feature, I have trouble 
> considering it a candidate for Swift 5, so I don't think there's a time 
> constraint forcing us to consider the "narrow" vs "huge" dimension. What's 
> the best thing for the language and tools in the long term? This is a feature 
> that influences the semantics of potentially any call site in all Swift code, 
> which we'd have to live with forever if we accepted it now. Opening up the 
> compiler architecture to make custom importers easier to write is a great 
> solution to a ton of problems, including yours I think, without adding 
> complexity to the core language. Experience in .NET land seems to show it's a 
> great technique for integrating dynamic systems with static type systems, 
> without poking unnecessary holes in the static language's type system

I agree with Joe. I also think that it would be very important to compare both 
approaches in detail before choosing one, because the last thing we want is to 
end up with both in the language. And if this proposal is accepted, we might 
refrain from introducing custom importers later, even if they are the better 
long term solution.

I want Swift to continue to shine for a very long time because I enjoy this 
language and I just want to make sure we don’t jeopardize that by choosing a 
quick solution without taking in consideration other solutions.

> -Joe
> 
>> -Chris
>> 
>> 
>> ___
>> 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
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Joe Groff via swift-evolution


> On Nov 11, 2017, at 4:21 AM, Marcel Weiher  wrote:
> 
> 
> 
>> On Nov 10, 2017, at 19:04 , Joe Groff via swift-evolution 
>>  wrote:
>> 
>> I don't like the idea of some calls having wildly different semantics from 
>> others;
> 
> The obvious solution then is to make this proposal the general case and 
> current calls a specialization of that.

That'd be great, but Swift violates Gilad Bracha's golden rule by having static 
overloading, and throws bidirectional type inference on top, so our static name 
resolution can't be treated as a specialization of a dynamic name lookup 
mechanism in all cases.

-Joe
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread C. Keith Ray via swift-evolution
how does c code (and Python code, etc, other than ObjC) call Swift functions, 
methods, etc? 

C. Keith Ray
https://leanpub.com/wepntk <- buy my book?
http://agilesolutionspace.blogspot.com/
twitter: @ckeithray
http://www.thirdfoundationsw.com/keith_ray_resume_2014_long.pdf

> On Nov 11, 2017, at 6:29 AM, Joe Groff via swift-evolution 
>  wrote:
> 
> 
> 
>> On Nov 10, 2017, at 4:20 PM, Joe Groff  wrote:
>> 
>> 
>> 
 On Nov 10, 2017, at 4:12 PM, Charles Srstka  
 wrote:
 
 On Nov 10, 2017, at 5:51 PM, Joe Groff  wrote:
 
 
 
>> On Nov 10, 2017, at 3:45 PM, Charles Srstka  
>> wrote:
>> 
>> On Nov 10, 2017, at 5:36 PM, Joe Groff  wrote:
>> 
>> How `MyObject.foo(_:bar:)` gets implemented is its own business, as far 
>> as the compiler is concerned. The compile-time name resolution for the 
>> method isn't impacted.
>> 
>> -Joe
> 
> The compile-time name resolution for the method doesn’t happen *at all.*
 
 You declared the method in your @interface, and the compiler saw that and 
 brought it in as what Swift considers to be a regular method, and your 
 call on the Swift side was resolved to it by Swift's usual lookup rules. 
 To do what Chris is suggesting requires changing the way calls get 
 resolved in the compiler before the call is even formed.
>>> 
>>> The only thing that makes this the “usual lookup rules” is that the 
>>> Objective-C bridge has already been implemented.
>> 
>> As I mentioned in my original reply, I personally think the "importer" 
>> approach would be superior, and that in a perfect world we'd have type 
>> providers to make writing something like the ObjC importer but for a 
>> different language or other dynamic data source something that doesn't 
>> require invasive compiler hackery. The importer puts all of this:
>> 
>>> - It’s changing the compile-time name resolution! The Swift name is 
>>> foo(bar:), but it’s changing that to fooWithBar:!
>>> 
>>> - It’s changing the signature! The argument took a String, but now it’s 
>>> passing an NSString!
>>> 
>>> - It’s not resolving the method at compile-time! It’s passing the modified 
>>> method name and the arg list to some objc_msgSend() function, which 
>>> resolves it dynamically in a way that user code can intercept and interpret 
>>> at runtime!
>>> 
>>> I’m just not seeing the conceptual difference here.
>> 
>> below the fold as far as the rest of the language is concerned. You could 
>> just as well written what the importer synths up in Swift directly:
>> 
>> func foo(bar: String) {
>> unsafeBitCast(objc_msgSend, to: @convention(c) (AnyObject, Selector, 
>> NSString) -> ().self)(self, "fooWithBar:", NSString(bar))
>> }
>> 
>> and the rest of the language would be none the wiser.
> 
> Though, since you bring up objc_msgSend, the way it works in ObjC might be a 
> better fit for Swift's name lookup model, since their keyword argument models 
> are similar. If Swift had a 'method of last resort' like ObjC's, say as a 
> strawman you could overload the '.' operator, then you could use it to 
> provide an implementation for a method given a compound name in a similar 
> way. So if you had:
> 
> struct Dynamic { func .(methodName: String) -> (Any...) -> Int }
> 
> let x = Dynamic()
> x.foo(x: 0, y: 1)
> 
> Then, when we do name lookup into x for foo(x:y:) and that fails, we'd fall 
> back to turning this into x.`func .`("foo(x:y:)")(0, 1). It would take a bit 
> more work to turn this into something like a Python call, but would fit 
> Swift's language model better.
> 
> -Joe
> 
> 
> ___
> 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


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Joe Groff via swift-evolution


> On Nov 10, 2017, at 8:35 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> 
>> On Nov 10, 2017, at 6:12 PM, Slava Pestov via swift-evolution 
>>  wrote:
>> 
>> 
>> 
>>> On Nov 10, 2017, at 6:10 PM, Matthew Johnson via swift-evolution 
>>>  wrote:
>>> 
>>> Setting this aside, I’m very curious to hear whether type providers 
>>> influence your thinking after you’ve had a chance to look into them.  I 
>>> have always thought they were very cool.
>> 
>> I’m in favor of solving this problem with something like type providers 
>> also. The required compiler changes would be significant but would also 
>> clean up the interface between the ClangImporter, Sema and Serialization. If 
>> done right it would be a net gain that would benefit all users, instead of 
>> just adding YetAnotherCornerCase™ that makes implementation maintainers 
>> curse and scream.
> 
> I find it ironic that you’re talking pejoratively about a feature that has 
> very narrow impact, complaining about how much of an impact on the compiler 
> it would have, and then pine for a hugely invasive feature - one that would 
> cause a ton of code churn, and probably wouldn’t actually be enough to 
> eliminate the special cases in place because of ObjC interop.

You underestimate the impact this would have on function call type checking, 
but since this is an additive, non-ABI-stability feature, I have trouble 
considering it a candidate for Swift 5, so I don't think there's a time 
constraint forcing us to consider the "narrow" vs "huge" dimension. What's the 
best thing for the language and tools in the long term? This is a feature that 
influences the semantics of potentially any call site in all Swift code, which 
we'd have to live with forever if we accepted it now. Opening up the compiler 
architecture to make custom importers easier to write is a great solution to a 
ton of problems, including yours I think, without adding complexity to the core 
language. Experience in .NET land seems to show it's a great technique for 
integrating dynamic systems with static type systems, without poking 
unnecessary holes in the static language's type system

-Joe

> -Chris
> 
> 
> ___
> 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


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Joe Groff via swift-evolution


> On Nov 10, 2017, at 5:44 PM, Chris Lattner  wrote:
> 
>> On Nov 10, 2017, at 11:42 AM, Joe Groff via swift-evolution 
>>  wrote:
 
 On Nov 10, 2017, at 10:57 AM, Alejandro Martinez via swift-evolution 
  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.
> 
> I’m pretty sure it doesn’t, but good news: since Swift requires an 
> implementation before the proposal can be officially reviewed, you will be 
> able to look at the actual patch to make this decision.

And the goal of the pitch phase is to hopefully save you the tears of trying to 
implement something if it's a bad idea.

>> 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.
> 
> This is really gross.  The goal here is to make Python feel natural.  If you 
> oppose this proposal then we’ll have to find some other way to provide an 
> elegant experience:
>> x∫(0, "foo", bar: "bas”)
> 
> This is not going to be acceptable to users.

Is it? My choice of operator character is silly, but it's the same amount of 
syntactic overhead as an optional chain/force call. It's a fair sight better 
than x.call(args: ..., keywordArgs: ...), I hope you'd agree, and is something 
that works without any language change. You mentioned variadics as being 
inadequate for your purposes as a considered alternative, but a variadics model 
that wasn't based on type erasure to arrays and kept runtime type information 
about the argument tuple that was passed in, along with better reflection APIs 
for accessing that type info, might lead to something you can use by 
incrementally improving the expressivity of existing language features instead 
of adding new ones.

-Joe
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-11 Thread Gwendal Roué via swift-evolution
Hello,

>   • What is your evaluation of the proposal?

I'm neutral. My humble contribution is about the name of the method, since many 
reactions so far have a problem with the proposed filterMap name.

I'm found of Ruby's `compact` method. Its role is to filter out nils:

[1, 2, nil, 4].compact # => [1, 2 3]

This is not exactly what our discussed flatMap does, I know. Ruby's compact 
does not take a mapping closure. Swift's flatMap removes only one level of 
nils, as many contributors have reminded us. I know, I know.

I'd suggest `compactMap` as an alternative name, should `filterMap` find too 
much resistance:

[1, 2, nil, 4].compactMap { $0 } // [1, 2, 4]
["1", "foo"]..compactMap { Int($0) } // [1]

I'd even suggest adding `compact()` as a shorthand for `compactMap { $0 }`, 
since filtering out nils as a very common operation.

"Compact" has the advantage of being a short word. "Compacting" a collection 
would just mean removing its nils, a concept that could easily stick in 
developers' minds, as Ruby has shown.

>   • Is the problem being addressed significant enough to warrant a change 
> to Swift?

No. I too am guilty of having used flatMap when map was enough. Another name 
would not have changed this. It was just part of my learning phase.

Gwendal Roué

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Joe Groff via swift-evolution


> On Nov 10, 2017, at 4:20 PM, Joe Groff  wrote:
> 
> 
> 
>>> On Nov 10, 2017, at 4:12 PM, Charles Srstka  
>>> wrote:
>>> 
>>> On Nov 10, 2017, at 5:51 PM, Joe Groff  wrote:
>>> 
>>> 
>>> 
> On Nov 10, 2017, at 3:45 PM, Charles Srstka  
> wrote:
> 
> On Nov 10, 2017, at 5:36 PM, Joe Groff  wrote:
> 
> How `MyObject.foo(_:bar:)` gets implemented is its own business, as far 
> as the compiler is concerned. The compile-time name resolution for the 
> method isn't impacted.
> 
> -Joe
 
 The compile-time name resolution for the method doesn’t happen *at all.*
>>> 
>>> You declared the method in your @interface, and the compiler saw that and 
>>> brought it in as what Swift considers to be a regular method, and your call 
>>> on the Swift side was resolved to it by Swift's usual lookup rules. To do 
>>> what Chris is suggesting requires changing the way calls get resolved in 
>>> the compiler before the call is even formed.
>> 
>> The only thing that makes this the “usual lookup rules” is that the 
>> Objective-C bridge has already been implemented.
> 
> As I mentioned in my original reply, I personally think the "importer" 
> approach would be superior, and that in a perfect world we'd have type 
> providers to make writing something like the ObjC importer but for a 
> different language or other dynamic data source something that doesn't 
> require invasive compiler hackery. The importer puts all of this:
> 
>> - It’s changing the compile-time name resolution! The Swift name is 
>> foo(bar:), but it’s changing that to fooWithBar:!
>> 
>> - It’s changing the signature! The argument took a String, but now it’s 
>> passing an NSString!
>> 
>> - It’s not resolving the method at compile-time! It’s passing the modified 
>> method name and the arg list to some objc_msgSend() function, which resolves 
>> it dynamically in a way that user code can intercept and interpret at 
>> runtime!
>> 
>> I’m just not seeing the conceptual difference here.
> 
> below the fold as far as the rest of the language is concerned. You could 
> just as well written what the importer synths up in Swift directly:
> 
> func foo(bar: String) {
>  unsafeBitCast(objc_msgSend, to: @convention(c) (AnyObject, Selector, 
> NSString) -> ().self)(self, "fooWithBar:", NSString(bar))
> }
> 
> and the rest of the language would be none the wiser.

Though, since you bring up objc_msgSend, the way it works in ObjC might be a 
better fit for Swift's name lookup model, since their keyword argument models 
are similar. If Swift had a 'method of last resort' like ObjC's, say as a 
strawman you could overload the '.' operator, then you could use it to provide 
an implementation for a method given a compound name in a similar way. So if 
you had:

struct Dynamic { func .(methodName: String) -> (Any...) -> Int }

let x = Dynamic()
x.foo(x: 0, y: 1)

Then, when we do name lookup into x for foo(x:y:) and that fails, we'd fall 
back to turning this into x.`func .`("foo(x:y:)")(0, 1). It would take a bit 
more work to turn this into something like a Python call, but would fit Swift's 
language model better.

-Joe


___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] async void

2017-11-11 Thread Yuta Koshizawa via swift-evolution
If you replace `async` with `throws`, you can get answers.


> Can you declare an async closure variable?

Yes. Like `let throwingClosure:() throws -> Void = { ... }`.


> Can a non-async closure be passed to a function expecting a async closure?

Yes. Like we can pass `() -> Void` to a function expecting a throwing
closure `() throws -> Void`.

It is possible because `(Foo) throws -> Bar` is a supertype of `(Foo)
-> Bar`. `(Foo) async -> Bar` is a supertype of `(Foo) -> Bar` in the
same way.

To treat an async function as a sync function is legal. It is similar
to make a `Promise` by `Promise(value)` which is completed
immediately.


> Can an async closure be passed to a function expecting a non-async closure?

No. `() -> Void` is a subtype of `() async -> Void`. It is same as
passing `() throws -> Void` to a function expecting `() -> Void` is
not allowed.


> It’s weird to me that we would allow you to have async void closures but not 
> async void functions

I am not sure what you mean. "async void closures" and "async void
functions" have a same type. Following two are almost same.

```
func foo() async -> Void { ... }
let foo: () async -> Void = { ... }
```

--
Yuta


2017-11-11 11:02 GMT+09:00 Adam Kemp :
> I’m not sure that answered my questions.
>
> Can I do this?
>
> let asyncClosure:() async -> Void = { await doSomethingAsync() } // Can you
> declare an async closure variable?
>
> beginAsync(asyncClosure)
>
>
> What about this?
>
> let syncClosure:() -> Void = { doSomethingSync() }
>
> beginAsync(syncClosure) // Can a non-async closure be passed to a function
> expecting a async closure?
>
>
> And this?
>
>
> func callSyncClosure(_ closure:() -> ()) { closure() }
>
>
> let asyncClosure:() async -> Void = { await doSomethingAsync() }
>
>
> callSyncClosure(asyncClosure) // Can an async closure be passed to a
> function expecting a non-async closure?
>
>
> Here are my thoughts on each of these:
>
> Can you declare an async closure variable? If async is part of the type then
> it would be very strange not to allow this. I think the proposal implies
> that you can, but only by way of an example about inferring whether a
> closure is async or not.
>
> Can a non-async closure be passed to a function expecting a sync closure?
> This seems like an obvious conversion. I feel like disallowing this would
> probably make things harder, but I haven’t thought it through enough to say
> exactly how. Are there reasons that this shouldn’t work, though?
>
> Can an async closure be passed to a function expecting a sync closure? This
> may be controversial, but I think this should be allowed too. I think a
> caller that expects a void-returning synchronous function should be able to
> call an async function and treat it as a call-and-forget.
>
> It’s weird to me that we would allow you to have async void closures but not
> async void functions, but in order to support beginAsync we have to have
> async void closures. So if we can make that work then why couldn’t we just
> make async void functions work and dispense with beginAsync entirely?
>
> On Nov 10, 2017, at 1:38 AM, Yuta Koshizawa via swift-evolution
>  wrote:
>
> I’m not sure how the proposed design handles type checking for async
> closures. Is async part of the type? Can I declare a local closure variable
> as async? What are the rules for conversion between async and non-async
> closures? Is it a warning or error to use a closure literal without an async
> keyword that is assigned to an async closure variable or passed as an async
> closure argument?
>
>
> It has been already realized for `throws`.
>
> ```
> // This works in Swift 4
> func foo(_ f: (Bar) throws -> Baz)
>
> // This can be checked in the same way
> func foo(_ f: (Bar) async -> Baz)
> ```
>
> Proposed `async/await` in Swift are analogous to `throws/try`. So a
> lot of things about `async/await` can be imagined when we think about
> `throws/try`. It is also true for `(Foo) async -> Void`. We can use it
> in the same way as we use `(Foo) throws -> Void`.
>
> `async/await` as an analogy to `throws/try` works well because both of
> them can be mapped to monads. `throws` is similar to `Result` and
> `async` is similar to `Promise` ( `Future` ).
>
> ```
> // `a` and `b` are similar
> func a() throws -> Int
> func b() -> Result
>
> // `c` and `d` are similar
> func c() async -> Int
> func d() -> Promise
>
> // `a` : `b` == `c` : `d`
> // `a` : `c` == `b` : `d`
> ```
>
> `try` and `await` are also similar to `flatMap`. ( I think most
> popular `Promise` is one in JavaScript. Although it does not have
> `flatMap`, its `then` method can be considered as `flatMap`. )
>
> ```
> let x = try a()
> // uses `x` here
>
> b().flatMap { x in
>  // uses `x` here
> }
>
> let y = await c()
> // uses `y` here
>
> d().flatMap { y in
>  // uses `y` here
> }
> ```
>
> So `throws` : `try` : `Result` == `async` : `await` : `Promise` and
> `throws` : `async` == `try` : 

Re: [swift-evolution] [Review] SE-0187: Introduce Sequence.filterMap(_:)

2017-11-11 Thread Tino Heth via swift-evolution


> Am 10.11.2017 um 23:32 schrieb Max Moiseev :
> 
>> extension Collection {
>>  func filterMap(transform: (Element) -> T, include: (T) -> Bool) -> 
>> [T] {
>>  return self.map(transform).filter(include)
>>  }
>> }
> 
> I understand the risk of diverging the discussion, but still, what’s the 
> benefit of having this function over using the built-in 
> `.lazy.map{}.filter{}` ?

I didn’t want to write any additional posts in this thread ;-), but as you ask 
a concrete question:
Imho there isn't any benefit over just using the two methods — it might be 
different for special cases with default values for one of the parameters (like 
getting rid of NaN, Zero or Infinity in a collection of floats), but I wouldn’t 
expect any of those to be part of the stdlib.
It’s just that this function is the natural interpretation of its name 
(especially for someone who knows flatMap), and I encountered people who are 
convinced that flatMap on Collections of Optionals is just like that: You map, 
you filter, you return the result (some even thought it’s the other way round, 
filtering being the first step).
Please note that the actual implementation of the method doesn’t matter at all 
for me — what matters is expectation (after all, I wouldn’t rename flatMap to 
joinMap), and the expectation for a filter is quite clear.

What kept the dispute alive that long is not that much that I think filterMap 
is a bad name per se, it is the widespread belief that it is a better 
description than flatMap.
Me and others strongly disagree here, and I’m quite sure no argument can change 
my mind on that. Therefor, the whole basis of the discussion is flawed, and I 
would be quite disappointed if the rationale for the acceptance of this 
proposal would be that flatMap is a wrong name, and filterMap is correct.
The real question should be if the renaming is beneficial for developers — and 
in this regard, wrong beliefs can work as good a good as true ones: As many 
people seem to have the same misconception about flatMap, it might be better to 
accept that (although I would like to see Kevin Ballards idea implemented 
anyways).

Concatenation is such a case: It doesn’t follow the laws of addition at all, 
but still, the same operator that is well established for adding numbers was 
chosen for it, because of the popular believe that joining two collections is 
like adding two numbers.

Tino___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Marcel Weiher via swift-evolution


> On Nov 10, 2017, at 19:04 , Joe Groff via swift-evolution 
>  wrote:
> 
> I don't like the idea of some calls having wildly different semantics from 
> others;

The obvious solution then is to make this proposal the general case and current 
calls a specialization of that.

Marcel

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Tino Heth via swift-evolution
> Example Usage
> 

Swift is quite flexible on what can act as a closure — would it be allowed to 
use a dynamic callable in that context?
I guess forwarding of

let closure: ([(String, Int)]) -> Int  = DynamicCallableType()

to the dynamicCall method of DynamicCallableType isn’t that hard, but wouldn’t 
it be odd if the value of closure changes when you leave out its type?___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introduce user-defined dynamically "callable" types

2017-11-11 Thread Tino Heth via swift-evolution
I generally dislike „protocol magic“, but I think in this case, there is also a 
precedence for an (imho) better way:
There’s no „Subscriptable“ protocol, and I would prefer callable types to be 
handled in the same way (afaics, subscripts are already used as „callable with 
different braces“ today in some cases).

You mention subscripts in „Alternatives considered“, but without an explanation 
why you don’t want a new declaration kind for dynamicCall — and I think it 
could co-exist with the orthogonal use case that you mention.

- Tino

___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution