Re: [swift-evolution] [Discussion] Swift for Data Science / ML / Big Data analytics

2017-10-30 Thread John McCall via swift-evolution

> On Oct 31, 2017, at 12:43 AM, Chris Lattner  wrote:
> 
> JohnMC: question for you below.
> 
> On Oct 30, 2017, at 1:25 PM, Douglas Gregor  > wrote:
>>> 
>>> Thinking about the Perl case makes it clear to me that this should not be 
>>> built into the compiler as a monolithic thing.  Perl supports several 
>>> different types (SV/AV/HV) which represent different concepts (scalars, 
>>> arrays, hashes) so baking it all together into one thing would be the wrong 
>>> way to map it.  In fact, the magic we need is pretty small, and seems 
>>> generally useful for other things. Consider a design like this:
>>> 
>>> 
>>> // not magic, things like Int, String and many other conform to this. 
>>> protocol Pythonable {
>>>  init?(_ : PythonObject)
>>>  func toPython() -> PythonObject
>>> }
>> 
>> It’s not magic unless you expect the compiler or runtime to help with 
>> conversion between Int/String/etc. and PythonObject, as with 
>> _ObjectiveCBridgeable.
> 
> Right, as I said above “not magic”.  The conformances would be manually 
> implemented in the Python overlay.  This provides a free implicit conversion 
> from "T -> Pythonable” for the T’s we care about, and a failable init from 
> Python back to Swift types.
> 
>>> // Not magic.
>>> struct PythonObject : /*protocols below*/ {
>>>   var state : UnsafePointer
>>> 
>>>   subscript(_ : Pythonable…) -> PythonObject {
>>> ...
>>>   }
>>> }
>>> 
>>> // Magic, must be on the struct definition.  
>>> // Could alternatively allow custom copy/move/… ctors like C++.
>>> protocol CustomValueWitnessTable {
>>>  static func init(..)
>>>  static func copy(..)
>>>  static func move(..)
>>>  static func destroy(..)
>>> }
>> 
>> Swift’s implementation model supports this. As a surface-level construct 
>> it’s going to be mired in UnsafeMutablePointers, and it’s not at all clear 
>> to me that we want this level of control there. 
> 
> There are two ways to implement it:
> 1) static func’s like the above, which are implemented as UnsafePointer's
> 2) Proper language syntax akin to the C++ “rule of 5”.
> 
> The pro’s and con’s of the first approach:
> 
> pro) full explicit control over what happens
> pro) no other new language features necessary to implement this.  The second 
> approach would need something like ownership to be in place.
> con) injects another avenue of unsafety (though it would be explicit, so it 
> isn’t that bad).  It isn’t obvious to me that approach #2 can be safe, but I 
> haven’t thought about it enough.
> ???) discourages people from using this protocol because of its explicit 
> unsafety.
> 
> I can think of two things that could tip the scale of the discussion:
> 
> a) The big question is whether we *want* the ability to write custom 
> rule-of-5 style behavior for structs, or if we want it to only be used in 
> extreme cases (like bridging interop in this proposal).  If we *want* to 
> support it someday, then adding proper “safe” support is best (if possible).  
> If we don’t *want* people to use it, then making it Unsafe and ugly is a 
> reasonable way to go.
> 
> b) The ownership proposal is likely to add deinit's to structs.  If it also 
> adds explicit move initializers, then it is probably the right thing to add 
> copy initializers also (and thus go with approach #2).  That said,  I’m not 
> sure how the move initializers will be spelled or if that is the likely 
> direction.  If it won’t add these, then it is probably better to go with 
> approach #1.  John, what do you think?

I was hoping not to have to add explicit move/copy initializers, perhaps ever.  
I would suggest one of two things:
  - We could add a Builtin type for these types in Swift.  Because of our 
architecture, this is mostly an IRGen task.
  - We could start working on C++ import.  C++ import is a huge task, but we 
don't really need most of it for this.

John.

> 
>> Presumably, binding to Python is going to require some compiler 
>> effort—defining how it is that Python objects are 
>> initialized/copied/moved/destroyed seems like a reasonable part of that 
>> effort.
> 
> Actually no.  If we add these three proposals, there is no other python (or 
> perl, etc…) specific support needed.  It is all implementable in the overlay.
> 
>>> // Magic, allows anyobject-like member lookup on a type when lookup 
>>> otherwise fails.
>>> protocol DynamicMemberLookupable {
>>>   associatedtype MemberLookupResultType
>>>   func dynamicMemberLookup(_ : String) -> MemberLookupResultType
>>> }
>> 
>> AnyObject lookup looks for an actual declaration on any type anywhere. One 
>> could extend that mechanism to, say, return all Python methods and assume 
>> that you can call any Python method with any PythonObject instance. 
>> AnyObject lookup is fairly unprincipled as a language feature, because 
>> there’s no natural scope in which to perform name lookup, and involves hacks 
>> at many levels that don’t always 

Re: [swift-evolution] [Discussion] Swift for Data Science / ML / Big Data analytics

2017-10-30 Thread Douglas Gregor via swift-evolution


> On Oct 30, 2017, at 9:43 PM, Chris Lattner  wrote:
> 
> JohnMC: question for you below.
> 
> On Oct 30, 2017, at 1:25 PM, Douglas Gregor  > wrote:
>>> 
>>> Thinking about the Perl case makes it clear to me that this should not be 
>>> built into the compiler as a monolithic thing.  Perl supports several 
>>> different types (SV/AV/HV) which represent different concepts (scalars, 
>>> arrays, hashes) so baking it all together into one thing would be the wrong 
>>> way to map it.  In fact, the magic we need is pretty small, and seems 
>>> generally useful for other things. Consider a design like this:
>>> 
>>> 
>>> // not magic, things like Int, String and many other conform to this. 
>>> protocol Pythonable {
>>>  init?(_ : PythonObject)
>>>  func toPython() -> PythonObject
>>> }
>> 
>> It’s not magic unless you expect the compiler or runtime to help with 
>> conversion between Int/String/etc. and PythonObject, as with 
>> _ObjectiveCBridgeable.
> 
> Right, as I said above “not magic”.  The conformances would be manually 
> implemented in the Python overlay.  This provides a free implicit conversion 
> from "T -> Pythonable” for the T’s we care about, and a failable init from 
> Python back to Swift types.

Note that, under this scheme,

let p: Pythonable = 17
let i: Int = p as! i

will work if Int is Pythonable, but not when p comes back from Python. 

> 
>>> // Not magic.
>>> struct PythonObject : /*protocols below*/ {
>>>   var state : UnsafePointer
>>> 
>>>   subscript(_ : Pythonable…) -> PythonObject {
>>> ...
>>>   }
>>> }
>>> 
>>> // Magic, must be on the struct definition.  
>>> // Could alternatively allow custom copy/move/… ctors like C++.
>>> protocol CustomValueWitnessTable {
>>>  static func init(..)
>>>  static func copy(..)
>>>  static func move(..)
>>>  static func destroy(..)
>>> }
>> 
>> Swift’s implementation model supports this. As a surface-level construct 
>> it’s going to be mired in UnsafeMutablePointers, and it’s not at all clear 
>> to me that we want this level of control there. 
> 
> There are two ways to implement it:
> 1) static func’s like the above, which are implemented as UnsafePointer's
> 2) Proper language syntax akin to the C++ “rule of 5”.
> 
> The pro’s and con’s of the first approach:
> 
> pro) full explicit control over what happens
> pro) no other new language features necessary to implement this.  The second 
> approach would need something like ownership to be in place.
> con) injects another avenue of unsafety (though it would be explicit, so it 
> isn’t that bad).  It isn’t obvious to me that approach #2 can be safe, but I 
> haven’t thought about it enough.
> ???) discourages people from using this protocol because of its explicit 
> unsafety.

con) much of the UnsafePointer interface is based on the value witness table, 
so one has to step lightly or work with something like 
COpaquePointer/UnsafePointer.

> 
> I can think of two things that could tip the scale of the discussion:
> 
> a) The big question is whether we *want* the ability to write custom 
> rule-of-5 style behavior for structs, or if we want it to only be used in 
> extreme cases (like bridging interop in this proposal).  If we *want* to 
> support it someday, then adding proper “safe” support is best (if possible).  
> If we don’t *want* people to use it, then making it Unsafe and ugly is a 
> reasonable way to go.
> 
> b) The ownership proposal is likely to add deinit's to structs.  If it also 
> adds explicit move initializers, then it is probably the right thing to add 
> copy initializers also (and thus go with approach #2).  That said,  I’m not 
> sure how the move initializers will be spelled or if that is the likely 
> direction.  If it won’t add these, then it is probably better to go with 
> approach #1.  John, what do you think?
> 
>> Presumably, binding to Python is going to require some compiler 
>> effort—defining how it is that Python objects are 
>> initialized/copied/moved/destroyed seems like a reasonable part of that 
>> effort.
> 
> Actually no.  If we add these three proposals, there is no other python (or 
> perl, etc…) specific support needed.  It is all implementable in the overlay.

Support for working with Python objects would be implementable in the overlay, 
but the result isn’t necessarily ergonomic (e.g., my “as!” case from a 
Python-generated integer object to Int, shown above). That might be fine! More 
comments on this below.

> 
>>> // Magic, allows anyobject-like member lookup on a type when lookup 
>>> otherwise fails.
>>> protocol DynamicMemberLookupable {
>>>   associatedtype MemberLookupResultType
>>>   func dynamicMemberLookup(_ : String) -> MemberLookupResultType
>>> }
>> 
>> AnyObject lookup looks for an actual declaration on any type anywhere. One 
>> could extend that mechanism to, say, return all Python methods and assume 
>> that you can call any Python 

Re: [swift-evolution] [Discussion] Swift for Data Science / ML / Big Data analytics

2017-10-30 Thread Douglas Gregor via swift-evolution


> On Oct 30, 2017, at 2:54 PM, David Kopecky  wrote:
> 
> To Chris’s use case point, I see Python -> Swift interop as a very common use 
> case in data science / ML for speeding up certain functions/modules by 
> embedding Swift into Python, like you can with, say, ctypes or python 
> extensions in dynamic C libraries. This is very common practice in the Python 
> universe, it just could be a lot better with Swift instead.
> 
> Things like this *sort of* exist with Swift 
> (https://gist.github.com/jiaaro/e111f0f64d0cdb8aca38 
> ), but it’s not really 
> very mature or functional.
> 
> I would LOVE to be able to speed up a lot of python code by implementing 
> swift libraries and importing into python. 

There are a bunch of ways one could export Swift functionality to Python, from 
a library solution like the C++ Boost.Python 
(http://www.boost.org/doc/libs/1_65_1/libs/python/doc/html/index.html 
), to 
code generators like SWIG or, with some future expansion of metadata, directly 
at runtime via reflection facilities. Python’s dynamic nature makes this 
direction easier.

The harder challenge (IMO!) is to get a Python library into Swift, because 
there isn’t a lot of type information in Python, so you have to show the Python 
in the much-more-strongly-typed Swift somehow (and keep it usable).

- Doug

> 
> - David
> 
>> On Oct 30, 2017, at 13:25, Douglas Gregor via swift-evolution 
>> > wrote:
>> 
>> 
>> 
>>> On Oct 29, 2017, at 1:34 PM, Chris Lattner via swift-evolution 
>>> > wrote:
>>> 
 
 On Oct 29, 2017, at 8:23 AM, Chris Lattner via swift-evolution 
 > wrote:
 
 
> On Oct 29, 2017, at 4:04 AM, Lukas Stabe  > wrote:
> 
>> On 28. Oct 2017, at 23:10, Chris Lattner via swift-evolution 
>> > wrote:
>> 
>> … which is to say, exactly identical to the Python version except that 
>> new variables need to be declared with let/var.  This can be done by 
>> blessing Python.Object (which is identical to “PyObject*” at the machine 
>> level) with some special dynamic name lookup behavior:  Dot syntax turns 
>> into a call to PyObject_GetAttrString, subscripts turn into 
>> PyObject_GetItem, calls turn into PyObject_Call, etc.  ARC would be 
>> implemented with INCREF etc.
> 
> That sounds like a very interesting prospect. Do you think it would make 
> sense to make the language features that facilitate this (dynamic 
> dispatch of method calls, property accesses, subscript and ARC) available 
> to Swift classes annotated in some way, so that interop like this can be 
> implemented as a library without special treatment by the Swift compiler? 
> This could also enable more dynamic DSL like features.
 
 I haven’t explored enough of the design space to be sure, but I’d want to 
 make sure that a library version of this could be done without giving up 
 ergonomics of the result.  If you were interested in being able to interop 
 with other languages that are dynamically typed and reference counted, 
 then something like this could be possible in principle:
>>> 
>>> Thinking about the Perl case makes it clear to me that this should not be 
>>> built into the compiler as a monolithic thing.  Perl supports several 
>>> different types (SV/AV/HV) which represent different concepts (scalars, 
>>> arrays, hashes) so baking it all together into one thing would be the wrong 
>>> way to map it.  In fact, the magic we need is pretty small, and seems 
>>> generally useful for other things. Consider a design like this:
>>> 
>>> 
>>> // not magic, things like Int, String and many other conform to this. 
>>> protocol Pythonable {
>>>  init?(_ : PythonObject)
>>>  func toPython() -> PythonObject
>>> }
>> 
>> It’s not magic unless you expect the compiler or runtime to help with 
>> conversion between Int/String/etc. and PythonObject, as with 
>> _ObjectiveCBridgeable.
>> 
>>> 
>>> // Not magic.
>>> struct PythonObject : /*protocols below*/ {
>>>   var state : UnsafePointer
>>> 
>>>   subscript(_ : Pythonable…) -> PythonObject {
>>> ...
>>>   }
>>> }
>>> 
>>> // Magic, must be on the struct definition.  
>>> // Could alternatively allow custom copy/move/… ctors like C++.
>>> protocol CustomValueWitnessTable {
>>>  static func init(..)
>>>  static func copy(..)
>>>  static func move(..)
>>>  static func destroy(..)
>>> }
>> 
>> Swift’s implementation model supports this. As a surface-level construct 
>> it’s going to be mired in UnsafeMutablePointers, and it’s not at all clear 

Re: [swift-evolution] [Discussion] Swift for Data Science / ML / Big Data analytics

2017-10-30 Thread Chris Lattner via swift-evolution
JohnMC: question for you below.

On Oct 30, 2017, at 1:25 PM, Douglas Gregor  wrote:
>> 
>> Thinking about the Perl case makes it clear to me that this should not be 
>> built into the compiler as a monolithic thing.  Perl supports several 
>> different types (SV/AV/HV) which represent different concepts (scalars, 
>> arrays, hashes) so baking it all together into one thing would be the wrong 
>> way to map it.  In fact, the magic we need is pretty small, and seems 
>> generally useful for other things. Consider a design like this:
>> 
>> 
>> // not magic, things like Int, String and many other conform to this. 
>> protocol Pythonable {
>>  init?(_ : PythonObject)
>>  func toPython() -> PythonObject
>> }
> 
> It’s not magic unless you expect the compiler or runtime to help with 
> conversion between Int/String/etc. and PythonObject, as with 
> _ObjectiveCBridgeable.

Right, as I said above “not magic”.  The conformances would be manually 
implemented in the Python overlay.  This provides a free implicit conversion 
from "T -> Pythonable” for the T’s we care about, and a failable init from 
Python back to Swift types.

>> // Not magic.
>> struct PythonObject : /*protocols below*/ {
>>   var state : UnsafePointer
>> 
>>   subscript(_ : Pythonable…) -> PythonObject {
>> ...
>>   }
>> }
>> 
>> // Magic, must be on the struct definition.  
>> // Could alternatively allow custom copy/move/… ctors like C++.
>> protocol CustomValueWitnessTable {
>>  static func init(..)
>>  static func copy(..)
>>  static func move(..)
>>  static func destroy(..)
>> }
> 
> Swift’s implementation model supports this. As a surface-level construct it’s 
> going to be mired in UnsafeMutablePointers, and it’s not at all clear to me 
> that we want this level of control there. 

There are two ways to implement it:
1) static func’s like the above, which are implemented as UnsafePointer's
2) Proper language syntax akin to the C++ “rule of 5”.

The pro’s and con’s of the first approach:

pro) full explicit control over what happens
pro) no other new language features necessary to implement this.  The second 
approach would need something like ownership to be in place.
con) injects another avenue of unsafety (though it would be explicit, so it 
isn’t that bad).  It isn’t obvious to me that approach #2 can be safe, but I 
haven’t thought about it enough.
???) discourages people from using this protocol because of its explicit 
unsafety.

I can think of two things that could tip the scale of the discussion:

a) The big question is whether we *want* the ability to write custom rule-of-5 
style behavior for structs, or if we want it to only be used in extreme cases 
(like bridging interop in this proposal).  If we *want* to support it someday, 
then adding proper “safe” support is best (if possible).  If we don’t *want* 
people to use it, then making it Unsafe and ugly is a reasonable way to go.

b) The ownership proposal is likely to add deinit's to structs.  If it also 
adds explicit move initializers, then it is probably the right thing to add 
copy initializers also (and thus go with approach #2).  That said,  I’m not 
sure how the move initializers will be spelled or if that is the likely 
direction.  If it won’t add these, then it is probably better to go with 
approach #1.  John, what do you think?

> Presumably, binding to Python is going to require some compiler 
> effort—defining how it is that Python objects are 
> initialized/copied/moved/destroyed seems like a reasonable part of that 
> effort.

Actually no.  If we add these three proposals, there is no other python (or 
perl, etc…) specific support needed.  It is all implementable in the overlay.

>> // Magic, allows anyobject-like member lookup on a type when lookup 
>> otherwise fails.
>> protocol DynamicMemberLookupable {
>>   associatedtype MemberLookupResultType
>>   func dynamicMemberLookup(_ : String) -> MemberLookupResultType
>> }
> 
> AnyObject lookup looks for an actual declaration on any type anywhere. One 
> could extend that mechanism to, say, return all Python methods and assume 
> that you can call any Python method with any PythonObject instance. AnyObject 
> lookup is fairly unprincipled as a language feature, because there’s no 
> natural scope in which to perform name lookup, and involves hacks at many 
> levels that don’t always work (e.g., AnyObject lookup… sometimes… fails 
> across multiple source files for hard-to-explain reasons). You’re taking on 
> that brokenness if you expand AnyObject lookup to another ecosystem.

Yeah, sorry, that’s not what I meant:

> Although it doesn’t really seem like AnyObject lookup is the thing you’re 
> asking for here. It seems more like you want dynamicMemberLookup(_:) to 
> capture “self” and the method name, and then be a callable thing as below…

That’s what I meant :-).

A type that implements this magic protocol would never fail name lookup: 
“foo.bar” would always fall back to calling: 

Re: [swift-evolution] continuations - "extensions on steroids" idea

2017-10-30 Thread Adam Kemp via swift-evolution
This I actually support. In C# the same concept exists in the form of partial 
classes. A class must be declared as partial everywhere in order to support it. 
It only works within a single assembly (similar to a module).

There are a few important use cases for this in C#:

1. Code generation. For instance, Interface Builder could modify a separate 
file for things like outlets and actions, and it could freely wipe and 
regenerate that file from scratch without touching any of your own code. Some 
people also generate parts of classes from templates while filling in the rest 
in another file. 

2. Cross platform code. A common strategy in C# is to have a class split into 
parts, where one part is compiled on all platforms, and the other files are 
each specific to one platform or another. For instance, you may have Foo.swift, 
Foo.macOS.swift, and Foo.iOS.swift. Foo.swift would be compiled on both 
platforms, but then the iOS build would only include Foo.iOS.swift. This is a 
preferred alternative to using #ifs.

3. The use case Mike described. Sometimes we fail at making classes small, or 
maybe someone else failed and we’re stuck with it. Splitting a single class 
into pieces can be useful to organize cohesive chunks. That’s not something I 
tend to encourage as a design pattern, but it still happens anyway. 

A related feature in C# is partial methods, which are just void-returning 
methods that have been declared as partial without an implementation. If an 
implementation is provided by another file (in another part of the partial 
class) then it is used. If no file provides an implementation then calls to 
that method are just stripped out by the compiler. This is also commonly used 
for cross-platform code. Maybe one platform needs to do something at a 
particular time but another doesn’t. Rather than using #ifs or having empty 
stubs in other platforms you can declare it partial and provide an 
implementation on just the one platform that needs it.

> On Oct 30, 2017, at 6:12 PM, Mike Kluev via swift-evolution 
>  wrote:
> 
> a general feeling that there are two very different use cases of extensions 
> -- one to extend own classes and another to extend other people classes; a 
> lengthy discussion in a nearby thread; a disparity of features of class and 
> it's extensions and different access right treatment depending upon whether 
> the extension is in the same with the main class or a different file lead me 
> to the following idea. hopefully you will find this idea useful and we may 
> even see it one day in swift.
> 
> introducing class / struct / enum continuations.
> 
> in a few words the are:
> 
> 1) "extensions on steroids". in fact very similar to Objective-C "class 
> extensions" but can be more than one and in more than one file.
> 
> 2) as good as the classes they continue (or other continuations they continue)
> 
> 3) can declare variables
> 
> 4) have full access to "private" members of the class or other continuations
> regardless whether they are in the same or in a different files. no need for 
> "public/internal/module" fallbacks to pass though files boundaries. similarly 
> the class itself can use private members of its continuations.
> 
> 5) "by invitation only" system. can only be written if declared by the class 
> or some continuation of it.
> 
> 6) A particular continuation only defined once (of course). There can be an 
> arbitrary number of different continuations to a class similar to extensions.
> 
> 7) alternative name considered: "extending" (as a noun). shall definitely be 
> a different name than say, "extension" with some bracket-syntax variation - 
> the two use cases are very different and shall be named differently.
> 
> 8) the particular syntax is preliminary of course. 
> 
> example:
> 
> = Some.swift ==
> 
> class Some {
> 
> private func private_method_of_class() {
> 
> // *** can use private methods of continuations even if they are in a 
> different file
> private_method_defined_in_a_continuation()
> }
> 
> // *** "by invitation" system
> 
> continuation Feature  // *** declaring a continuation
> continuation SomethingElse// *** Capitalized names, like classes
> }
> 
> = Some-Feature.swift ==
> 
> // *** similar naming convetion to "Some+Feature.swift"
> // used for extensions, just with "-" instead
> 
> // *** this is merely a naming convention, no need to
> necessarily follow it, can put more than one thing into
> a file, the continuation can reside in the same file as
> the main class fie, etc.
> 
> continuation Feature of Some {
> 
> // *** as good as class itself. first-class citizen
> // *** same syntax can be used for structs and enums
> 
> var x: Int // *** can declare variables
> 
> private func private_method_defined_in_a_continuation() {
> private_method_of_class()
> 
> // 

Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Adam Kemp via swift-evolution


> On Oct 30, 2017, at 5:36 PM, Noah Desch  wrote:
> 
> If I’m concerned with how much work I’ll have to do, no that’s not the key. 
> The key is how many files do I have to read myself (only those containing a 
> subclass or extension of my base class).

Why would you read any file before searching for usages and figuring out which 
files use that API? And the scope of that search is defined by the access 
level. 

> You seem to be conflating a near instantaneous search in an IDE

No, grep would be sufficient as well. The issue is still which files to grep in 
the first place. Everything else comes after that. If you manually read files 
looking for usages of an API you’re changing then I feel sorry for you. You’re 
doing things the hard way. 


> There doesn’t need to be anything in the language, I just need to have a 
> defined coding convention that contributors follow. As someone else said 
> upthread you have to be able to trust your fellow developers.

If you trust your fellow developers then you don’t need a new access scope. Use 
internal or public. 

I’m not going to go back and forth on this any longer. We’re going in circles. 
We just don’t agree, and this doesn’t appear to be going anywhere. 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Xiaodi Wu via swift-evolution
This idea has been discussed before and deemed inconsistent with Swift's
design for access levels. Any further access levels are pretty clearly out
of scope for Swift 5. I'll refer you to the list of focus areas here:

https://github.com/apple/swift-evolution


On Mon, Oct 30, 2017 at 20:30 Mike Kluev via swift-evolution <
swift-evolution@swift.org> wrote:

> On 31 October 2017 at 00:36, Noah Desch  wrote:
>
>>
>>
>> > On Oct 30, 2017, at 6:38 PM, Adam Kemp via swift-evolution <
>> swift-evolution@swift.org> wrote:
>> >
>> >
>> >
>> >> On Oct 30, 2017, at 2:23 PM, Mike Kluev  wrote:
>> >>
>> >> On 30 October 2017 at 19:49, Adam Kemp  wrote:
>> >>
>> >> How do you know there’s not an extension in this file without looking?
>> If you don’t know then you have to check. That puts it in the same bucket
>> as internal or public. The set of files you have to search through for
>> usages is the same.
>> >>
>> >>
>> >> I'd just search for "extension SomeClass", Xcode search result window
>> will list all files that have it.
>> >> or I will list all the users of "foo" if that's the one I am changing.
>> >
>> > When you do that search, which files do you include in the search?
>> That’s the key.
>>
>>
>> If I’m concerned with how much work I’ll have to do, no that’s not the
>> key. The key is how many files do I have to read myself (only those
>> containing a subclass or extension of my base class). You seem to be
>> conflating a near instantaneous search in an IDE with manually evaluating a
>> change’s impact to other source files in the module. “Classprivate" makes
>> significantly fewer files that I have to manually review compared to
>> “internal”.
>
>
> exactly. significantly fewer files or fragments of files - significantly
> fewer entries in the search results in other words.
>
> when in a pub:
>
> public / internal:
>   - may i have a pint of lager please? - sure, here you are
>
> classprivate / protected:
>   - may i have a pint of ale please?
>   - sure. are you a member of our club? we serve ale to members only
>   - errr. no. can i become a member?
>   - yes, it is free. just take a seat over there and fill this form
> first, once done i will bring you your ale.
>   - errr, thanks. may i have lager instead please?
>
> private:
>   - may i have a pint of potter please?
>   - sure. are you a member of our club?
>   - yes, i just filed the form, here it is.
>- are you aware that we serve potter only in that "core members
> only" private room?
>   - errr, no, how do i get there?
>   - ah, no sir, it is impossible. you would know if you can go there.
> it is by invitation only system.
>   - damn!! lager!
>
> i am dead sure they will serve much less ale than lager, don't you.
>
> Mike
>
> ___
> 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] classprivate protection level?

2017-10-30 Thread Mike Kluev via swift-evolution
On 31 October 2017 at 00:36, Noah Desch  wrote:

>
>
> > On Oct 30, 2017, at 6:38 PM, Adam Kemp via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> >
> >
> >> On Oct 30, 2017, at 2:23 PM, Mike Kluev  wrote:
> >>
> >> On 30 October 2017 at 19:49, Adam Kemp  wrote:
> >>
> >> How do you know there’s not an extension in this file without looking?
> If you don’t know then you have to check. That puts it in the same bucket
> as internal or public. The set of files you have to search through for
> usages is the same.
> >>
> >>
> >> I'd just search for "extension SomeClass", Xcode search result window
> will list all files that have it.
> >> or I will list all the users of "foo" if that's the one I am changing.
> >
> > When you do that search, which files do you include in the search?
> That’s the key.
>
>
> If I’m concerned with how much work I’ll have to do, no that’s not the
> key. The key is how many files do I have to read myself (only those
> containing a subclass or extension of my base class). You seem to be
> conflating a near instantaneous search in an IDE with manually evaluating a
> change’s impact to other source files in the module. “Classprivate" makes
> significantly fewer files that I have to manually review compared to
> “internal”.


exactly. significantly fewer files or fragments of files - significantly
fewer entries in the search results in other words.

when in a pub:

public / internal:
  - may i have a pint of lager please? - sure, here you are

classprivate / protected:
  - may i have a pint of ale please?
  - sure. are you a member of our club? we serve ale to members only
  - errr. no. can i become a member?
  - yes, it is free. just take a seat over there and fill this form
first, once done i will bring you your ale.
  - errr, thanks. may i have lager instead please?

private:
  - may i have a pint of potter please?
  - sure. are you a member of our club?
  - yes, i just filed the form, here it is.
   - are you aware that we serve potter only in that "core members
only" private room?
  - errr, no, how do i get there?
  - ah, no sir, it is impossible. you would know if you can go there.
it is by invitation only system.
  - damn!! lager!

i am dead sure they will serve much less ale than lager, don't you.

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


[swift-evolution] continuations - "extensions on steroids" idea

2017-10-30 Thread Mike Kluev via swift-evolution
a general feeling that there are two very different use cases of extensions
-- one to extend own classes and another to extend other people classes; a
lengthy discussion in a nearby thread; a disparity of features of class and
it's extensions and different access right treatment depending upon whether
the extension is in the same with the main class or a different file lead
me to the following idea. hopefully you will find this idea useful and we
may even see it one day in swift.

introducing class / struct / enum continuations.

in a few words the are:

1) "extensions on steroids". in fact very similar to Objective-C "class
extensions" but can be more than one and in more than one file.

2) as good as the classes they continue (or other continuations they
continue)

3) can declare variables

4) have full access to "private" members of the class or other continuations
regardless whether they are in the same or in a different files. no need
for "public/internal/module" fallbacks to pass though files boundaries.
similarly the class itself can use private members of its continuations.

5) "by invitation only" system. can only be written if declared by the
class or some continuation of it.

6) A particular continuation only defined once (of course). There can be an
arbitrary number of different continuations to a class similar to
extensions.

7) alternative name considered: "extending" (as a noun). shall definitely
be a different name than say, "extension" with some bracket-syntax
variation - the two use cases are very different and shall be named
differently.

8) the particular syntax is preliminary of course.

example:

= Some.swift ==

class Some {

private func private_method_of_class() {

// *** can use private methods of continuations even if they are in
a different file
private_method_defined_in_a_continuation()
}

// *** "by invitation" system

continuation Feature // *** declaring a continuation
continuation SomethingElse // *** Capitalized names, like classes
}

= Some-Feature.swift ==

// *** similar naming convetion to "Some+Feature.swift"
// used for extensions, just with "-" instead

// *** this is merely a naming convention, no need to
necessarily follow it, can put more than one thing into
a file, the continuation can reside in the same file as
the main class fie, etc.

continuation Feature of Some {

// *** as good as class itself. first-class citizen
// *** same syntax can be used for structs and enums

var x: Int // *** can declare variables

private func private_method_defined_in_a_continuation() {
private_method_of_class()

// *** can use private methods of the class or of other
continuations even if they are in a different file
}

// *** continuations are as good as classes and can
// *** declare other continuations if needed

continuation CanDoThis
}

= Any file ==

continuation Feature of Some { // *** error, continuation is already defined
}

continuation Other of Some { // *** error: Other is not a continuation of
Some
}

thoughts?

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


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Noah Desch via swift-evolution


> On Oct 30, 2017, at 6:38 PM, Adam Kemp via swift-evolution 
>  wrote:
> 
> 
> 
>> On Oct 30, 2017, at 2:23 PM, Mike Kluev  wrote:
>> 
>> On 30 October 2017 at 19:49, Adam Kemp  wrote:
>>  
>> How do you know there’s not an extension in this file without looking? If 
>> you don’t know then you have to check. That puts it in the same bucket as 
>> internal or public. The set of files you have to search through for usages 
>> is the same.
>> 
>> 
>> I'd just search for "extension SomeClass", Xcode search result window will 
>> list all files that have it.
>> or I will list all the users of "foo" if that's the one I am changing.
> 
> When you do that search, which files do you include in the search? That’s the 
> key.


If I’m concerned with how much work I’ll have to do, no that’s not the key. The 
key is how many files do I have to read myself (only those containing a 
subclass or extension of my base class). You seem to be conflating a near 
instantaneous search in an IDE with manually evaluating a change’s impact to 
other source files in the module. “Classprivate" makes significantly fewer 
files that I have to manually review compared to “internal”.



>> the good guideline from Obj-C was (and still is) using 
>> "SomeClass+ExtensionName" file naming convention that also helps.
> 
> That’s not sufficient because there’s nothing in the language that would 
> force people to follow this convention, and you can have extensions in any 
> file for any class.


There doesn’t need to be anything in the language, I just need to have a 
defined coding convention that contributors follow. As someone else said 
upthread you have to be able to trust your fellow developers.

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


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread James Froggatt via swift-evolution
 Begin Message  
Group: gmane.comp.lang.swift.evolution 
MsgID: 

Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Adam Kemp via swift-evolution


> On Oct 30, 2017, at 4:31 PM, Mike Kluev  wrote:
> 
> On 30 October 2017 at 23:14, Adam Kemp  > wrote:
> 
> > On Oct 30, 2017, at 4:10 PM, Mike Kluev  > > wrote:
> >
> > "classprivate" helps to resolve this problem. if it is marked so developer 
> > will at least think twice before making an extension to use it
> 
> Why would they think twice, though? You’ve told them extensions can use it, 
> and they’ve written an extension to use it. What did they do wrong? I don’t 
> think the rules are nearly as clear as for protected.
> 
> this is obvious: when they are writing a method in their own class and try to 
> call: some.foo() it will give them and access level error (or even before 
> that the autocomplete will not work as an early hint),


This is not the situation I was asking about. I was asking why would someone in 
a random file who is about to write an extension think twice about using this 
method? He wouldn’t, because you’ve told him using that method (in an 
extension) is fine. But you may not know about or approve of that code he’s 
writing, and you may later make a change that breaks that usage. The access 
level has not improved your ability to reason about what might break.

The root of our disagreement is in how we view extensions. There’s no real 
difference between code in an extension and code in some other 
class/struct/whatever. It’s still a client of the original class, not part of 
that class itself. It’s a separate thing. You’re thinking of an extension as 
part of the original class, but it’s not. Since anyone can write an extension, 
even in other modules, it has to be thought of as a separate thing, an external 
client. The author of the class has no control over or knowledge of extensions 
on that class, and the only way to be able to reason about whether a change to 
an API is safe is to use access levels that tell the author which files might 
be able to use that API.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Mike Kluev via swift-evolution
On 30 October 2017 at 23:14, Adam Kemp  wrote:

>
> > On Oct 30, 2017, at 4:10 PM, Mike Kluev  wrote:
> >
> > "classprivate" helps to resolve this problem. if it is marked so
> developer will at least think twice before making an extension to use it
>
> Why would they think twice, though? You’ve told them extensions can use
> it, and they’ve written an extension to use it. What did they do wrong? I
> don’t think the rules are nearly as clear as for protected.
>

this is obvious: when they are writing a method in their own class and try
to call: some.foo() it will give them and access level error (or even
before that the autocomplete will not work as an early hint), they will
reveal foo's definition, see "classprivate" in there and at that very point
take a pause, think and make a conscious decision whether they really want
it or not. if they really want it they will make an extension (which would
be a legitimate use of it) if they don't need it really - they will find
another way without making an extension. the (reasonable) expectation is
that such a "classprivate" will reduce the number of instances where "foo"
is used thus reducing the "working set" of instances i have to review when
making a change to it.

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


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Adam Kemp via swift-evolution


> On Oct 30, 2017, at 4:10 PM, Mike Kluev  wrote:
> 
> "classprivate" helps to resolve this problem. if it is marked so developer 
> will at least think twice before making an extension to use it

Why would they think twice, though? You’ve told them extensions can use it, and 
they’ve written an extension to use it. What did they do wrong? I don’t think 
the rules are nearly as clear as for protected.

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


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Mike Kluev via swift-evolution
On 30 October 2017 at 22:38, Adam Kemp  wrote:

>
> “specialprivate", by allowing any extension to access the API, would imply
> the same set of files as either internal or public. You can’t know ahead of
> time whether some random file in your module might make an extension that
> access that API so you have to search all files within that module. You
> would perform the search exactly the same way. It doesn’t help you as a
> library maintainer. You’re not going to save work by making something
> “specialprivate” instead of internal. Worst case is you actually convince
> yourself that you don’t have to search the whole module, and then you break
> something because of that misunderstanding. That’s why internal is better.
> It avoids obfuscating the actual implications of that access level.
>

i still see a value in it:

- i do a search for, say, "foo" (all files in the module)
- let's say 50 usages will be legitimate use from within the class or it's
extensions
- another 10 usages will be wrong, that mistakenly treated it's "internal /
public" as a permission to use.
- i found those instances which shall not be there (that mistakenly use it
as it is effectively public)
- i ask developers who did it to not do this again / fix the problem / etc
- some time later i can do the same mistake myself again or other people
will do the same mistake again and the process repeats.
- compiler doesn't help as it can't check
- it becomes a manual and error prone process

"classprivate" helps to resolve this problem. if it is marked so developer
will at least think twice before making an extension to use it - similar to
how marking a method "protected" stops people from using it without
subclassing - (and creating an extension for the sole purpose of using
despite of it's access level would qualify as "cheating", which we can
leave aside). with "internal / public" there is nothing stopping them for a
second and they can use it without even realising they are doing something
wrong. all IMHO.

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


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Adam Kemp via swift-evolution


> On Oct 30, 2017, at 2:23 PM, Mike Kluev  wrote:
> 
> On 30 October 2017 at 19:49, Adam Kemp  > wrote:
>  
> How do you know there’s not an extension in this file without looking? If you 
> don’t know then you have to check. That puts it in the same bucket as 
> internal or public. The set of files you have to search through for usages is 
> the same.
> 
> 
> I'd just search for "extension SomeClass", Xcode search result window will 
> list all files that have it.
> or I will list all the users of "foo" if that's the one I am changing.

When you do that search, which files do you include in the search? That’s the 
key.

> 
> the good guideline from Obj-C was (and still is) using 
> "SomeClass+ExtensionName" file naming convention that also helps.

That’s not sufficient because there’s nothing in the language that would force 
people to follow this convention, and you can have extensions in any file for 
any class.

The point I’m trying to make, again, is that the set of files that you would 
have to search through is the same. Once you know the set of files that need to 
be searched you can just search for actual usages of the API you’re changing 
(the method or property or whatever). The important thing is to know which 
files need to be searched in the first place. That’s what access level really 
controls.

Each access level implies a unique set of files that have to be searched. 
Public = all files in all clients. Internal = all files in this module. File 
private = just one file. Private = just one part of one file.

“specialprivate", by allowing any extension to access the API, would imply the 
same set of files as either internal or public. You can’t know ahead of time 
whether some random file in your module might make an extension that access 
that API so you have to search all files within that module. You would perform 
the search exactly the same way. It doesn’t help you as a library maintainer. 
You’re not going to save work by making something “specialprivate” instead of 
internal. Worst case is you actually convince yourself that you don’t have to 
search the whole module, and then you break something because of that 
misunderstanding. That’s why internal is better. It avoids obfuscating the 
actual implications of that access level.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Discussion] Swift for Data Science / ML / Big Data analytics

2017-10-30 Thread David Kopecky via swift-evolution
To Chris’s use case point, I see Python -> Swift interop as a very common use 
case in data science / ML for speeding up certain functions/modules by 
embedding Swift into Python, like you can with, say, ctypes or python 
extensions in dynamic C libraries. This is very common practice in the Python 
universe, it just could be a lot better with Swift instead.

Things like this *sort of* exist with Swift 
(https://gist.github.com/jiaaro/e111f0f64d0cdb8aca38 
), but it’s not really 
very mature or functional.

I would LOVE to be able to speed up a lot of python code by implementing swift 
libraries and importing into python. 

- David

> On Oct 30, 2017, at 13:25, Douglas Gregor via swift-evolution 
>  wrote:
> 
> 
> 
>> On Oct 29, 2017, at 1:34 PM, Chris Lattner via swift-evolution 
>> > wrote:
>> 
>>> 
>>> On Oct 29, 2017, at 8:23 AM, Chris Lattner via swift-evolution 
>>> > wrote:
>>> 
>>> 
 On Oct 29, 2017, at 4:04 AM, Lukas Stabe > wrote:
 
> On 28. Oct 2017, at 23:10, Chris Lattner via swift-evolution 
> > wrote:
> 
> … which is to say, exactly identical to the Python version except that 
> new variables need to be declared with let/var.  This can be done by 
> blessing Python.Object (which is identical to “PyObject*” at the machine 
> level) with some special dynamic name lookup behavior:  Dot syntax turns 
> into a call to PyObject_GetAttrString, subscripts turn into 
> PyObject_GetItem, calls turn into PyObject_Call, etc.  ARC would be 
> implemented with INCREF etc.
 
 That sounds like a very interesting prospect. Do you think it would make 
 sense to make the language features that facilitate this (dynamic dispatch 
 of method calls, property accesses, subscript and ARC) available to Swift 
 classes annotated in some way, so that interop like this can be 
 implemented as a library without special treatment by the Swift compiler? 
 This could also enable more dynamic DSL like features.
>>> 
>>> I haven’t explored enough of the design space to be sure, but I’d want to 
>>> make sure that a library version of this could be done without giving up 
>>> ergonomics of the result.  If you were interested in being able to interop 
>>> with other languages that are dynamically typed and reference counted, then 
>>> something like this could be possible in principle:
>> 
>> Thinking about the Perl case makes it clear to me that this should not be 
>> built into the compiler as a monolithic thing.  Perl supports several 
>> different types (SV/AV/HV) which represent different concepts (scalars, 
>> arrays, hashes) so baking it all together into one thing would be the wrong 
>> way to map it.  In fact, the magic we need is pretty small, and seems 
>> generally useful for other things. Consider a design like this:
>> 
>> 
>> // not magic, things like Int, String and many other conform to this. 
>> protocol Pythonable {
>>  init?(_ : PythonObject)
>>  func toPython() -> PythonObject
>> }
> 
> It’s not magic unless you expect the compiler or runtime to help with 
> conversion between Int/String/etc. and PythonObject, as with 
> _ObjectiveCBridgeable.
> 
>> 
>> // Not magic.
>> struct PythonObject : /*protocols below*/ {
>>   var state : UnsafePointer
>> 
>>   subscript(_ : Pythonable…) -> PythonObject {
>> ...
>>   }
>> }
>> 
>> // Magic, must be on the struct definition.  
>> // Could alternatively allow custom copy/move/… ctors like C++.
>> protocol CustomValueWitnessTable {
>>  static func init(..)
>>  static func copy(..)
>>  static func move(..)
>>  static func destroy(..)
>> }
> 
> Swift’s implementation model supports this. As a surface-level construct it’s 
> going to be mired in UnsafeMutablePointers, and it’s not at all clear to me 
> that we want this level of control there. Presumably, binding to Python is 
> going to require some compiler effort—defining how it is that Python objects 
> are initialized/copied/moved/destroyed seems like a reasonable part of that 
> effort.
> 
>> // Magic, allows anyobject-like member lookup on a type when lookup 
>> otherwise fails.
>> protocol DynamicMemberLookupable {
>>   associatedtype MemberLookupResultType
>>   func dynamicMemberLookup(_ : String) -> MemberLookupResultType
>> }
> 
> AnyObject lookup looks for an actual declaration on any type anywhere. One 
> could extend that mechanism to, say, return all Python methods and assume 
> that you can call any Python method with any PythonObject instance. AnyObject 
> lookup is fairly unprincipled as a language feature, because there’s no 
> natural scope in which to perform name lookup, and involves hacks at many 
> levels that don’t 

Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Mike Kluev via swift-evolution
On 30 October 2017 at 19:49, Adam Kemp  wrote:


> How do you know there’s not an extension in this file without looking? If
> you don’t know then you have to check. That puts it in the same bucket as
> internal or public. The set of files you have to search through for usages
> is the same.
>
>
I'd just search for "extension SomeClass", Xcode search result window will
list all files that have it.
or I will list all the users of "foo" if that's the one I am changing.

the good guideline from Obj-C was (and still is) using
"SomeClass+ExtensionName" file naming convention that also helps.

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


Re: [swift-evolution] [Discussion] Swift for Data Science / ML / Big Data analytics

2017-10-30 Thread Douglas Gregor via swift-evolution


> On Oct 29, 2017, at 1:34 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
>> 
>> On Oct 29, 2017, at 8:23 AM, Chris Lattner via swift-evolution 
>>  wrote:
>> 
>> 
>>> On Oct 29, 2017, at 4:04 AM, Lukas Stabe  wrote:
>>> 
 On 28. Oct 2017, at 23:10, Chris Lattner via swift-evolution 
  wrote:
 
 … which is to say, exactly identical to the Python version except that new 
 variables need to be declared with let/var.  This can be done by blessing 
 Python.Object (which is identical to “PyObject*” at the machine level) 
 with some special dynamic name lookup behavior:  Dot syntax turns into a 
 call to PyObject_GetAttrString, subscripts turn into PyObject_GetItem, 
 calls turn into PyObject_Call, etc.  ARC would be implemented with INCREF 
 etc.
>>> 
>>> That sounds like a very interesting prospect. Do you think it would make 
>>> sense to make the language features that facilitate this (dynamic dispatch 
>>> of method calls, property accesses, subscript and ARC) available to Swift 
>>> classes annotated in some way, so that interop like this can be implemented 
>>> as a library without special treatment by the Swift compiler? This could 
>>> also enable more dynamic DSL like features.
>> 
>> I haven’t explored enough of the design space to be sure, but I’d want to 
>> make sure that a library version of this could be done without giving up 
>> ergonomics of the result.  If you were interested in being able to interop 
>> with other languages that are dynamically typed and reference counted, then 
>> something like this could be possible in principle:
> 
> Thinking about the Perl case makes it clear to me that this should not be 
> built into the compiler as a monolithic thing.  Perl supports several 
> different types (SV/AV/HV) which represent different concepts (scalars, 
> arrays, hashes) so baking it all together into one thing would be the wrong 
> way to map it.  In fact, the magic we need is pretty small, and seems 
> generally useful for other things. Consider a design like this:
> 
> 
> // not magic, things like Int, String and many other conform to this. 
> protocol Pythonable {
>  init?(_ : PythonObject)
>  func toPython() -> PythonObject
> }

It’s not magic unless you expect the compiler or runtime to help with 
conversion between Int/String/etc. and PythonObject, as with 
_ObjectiveCBridgeable.

> 
> // Not magic.
> struct PythonObject : /*protocols below*/ {
>   var state : UnsafePointer
> 
>   subscript(_ : Pythonable…) -> PythonObject {
> ...
>   }
> }
> 
> // Magic, must be on the struct definition.  
> // Could alternatively allow custom copy/move/… ctors like C++.
> protocol CustomValueWitnessTable {
>  static func init(..)
>  static func copy(..)
>  static func move(..)
>  static func destroy(..)
> }

Swift’s implementation model supports this. As a surface-level construct it’s 
going to be mired in UnsafeMutablePointers, and it’s not at all clear to me 
that we want this level of control there. Presumably, binding to Python is 
going to require some compiler effort—defining how it is that Python objects 
are initialized/copied/moved/destroyed seems like a reasonable part of that 
effort.

> // Magic, allows anyobject-like member lookup on a type when lookup otherwise 
> fails.
> protocol DynamicMemberLookupable {
>   associatedtype MemberLookupResultType
>   func dynamicMemberLookup(_ : String) -> MemberLookupResultType
> }

AnyObject lookup looks for an actual declaration on any type anywhere. One 
could extend that mechanism to, say, return all Python methods and assume that 
you can call any Python method with any PythonObject instance. AnyObject lookup 
is fairly unprincipled as a language feature, because there’s no natural scope 
in which to perform name lookup, and involves hacks at many levels that don’t 
always work (e.g., AnyObject lookup… sometimes… fails across multiple source 
files for hard-to-explain reasons). You’re taking on that brokenness if you 
expand AnyObject lookup to another ecosystem.

Although it doesn’t really seem like AnyObject lookup is the thing you’re 
asking for here. It seems more like you want dynamicMemberLookup(_:) to capture 
“self” and the method name, and then be a callable thing as below...

> 
> // Magic, allows “overloaded/sugared postfix ()”.
> protocol CustomCallable {
>  func call( …)
> }
> 
> The only tricky thing about this is the call part of things.  At least in the 
> case of python, we want something like this:
> 
>   foo.bar(1, 2, a: x, b: y)
> 
> to turn into:
>  foo.dynamicMemberLookup(“bar”).call(1, 2, kwargs: [“a”:x, “b”:y])
> 
> We don’t want this to be a memberlookup of a value that has “bar” as a 
> basename and “a:” and “b:” as parameter labels.

Well, I think the MemberLookupResult is going to get the name “bar”, argument 
labels “_:_:a:b:”, and arguments “1”, “2”, “x”, “y”, 

Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Adam Kemp via swift-evolution

> On Oct 30, 2017, at 11:19 AM, Mike Kluev  wrote:
> 
> 
> On 30 October 2017 at 18:07, Adam Kemp  > wrote:
>> On Oct 30, 2017, at 10:57 AM, Mike Kluev > > wrote:
>> 
>> 
>> the new bucket would be "class and all of its extensions be them in the same 
>> file or in different files”.
> 
> That’s not a new bucket. It is equivalent to either internal or public, 
> depending on whether you want to extend this beyond the module boundary. The 
> set of code you would have to audit is the same.
> 
> it is different, see below:
> 
> === file: Some.swift
> 
> class Some {
>internal func foo() {
>   bar()
>}
>classprivate func better() {
>   good()
> }
> }
> 
> === file: Some+Bar.swift
> 
> extension Some {
>   internal func bar() {
>   foo()
>   }
>   classprivate func good() {
>   better()
>}
> }
> 
> === any other file (same module)
> 
> class Other {
> func x() {
> let some = Some()
> 
> some.foo() // ** UNWANTED!!
> 
> some.better() // error.  ** WANTED!
> }
> }

How do you know there’s not an extension in this file without looking? If you 
don’t know then you have to check. That puts it in the same bucket as internal 
or public. The set of files you have to search through for usages is the same.

> 
> I do not want to audit the class Other when I make a change to "foo" or 
> "bar", which are essentially "private" and only made "internal" because of 
> the language limitation in regards to "private" vs "multi-file class" issue.
> 
> 
> What does marking a method as “specialprivate” (my made up name for this new 
> access level) tell clients about who can use it or how it can be used?
> 
> it tells them: "you can't use this, unless you are writing an extension to 
> this class or making changes to this class itself”

There’s nothing special about an extension. Anyone can write an extension to 
any class. You shouldn’t need any special privileges to enable people to write 
extensions. You’re not gaining anything by introducing an interface only usable 
by extensions.

> 
> Mike
> 

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


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Mike Kluev via swift-evolution
On 30 October 2017 at 18:07, Adam Kemp  wrote:

> On Oct 30, 2017, at 10:57 AM, Mike Kluev  wrote:
>
>
> the new bucket would be "class and all of its extensions be them in the
> same file or in different files”.
>
>
> That’s not a new bucket. It is equivalent to either internal or public,
> depending on whether you want to extend this beyond the module boundary.
> The set of code you would have to audit is the same.
>

it is different, see below:

=== file: Some.swift

class Some {
   internal func foo() {
  bar()
   }
   classprivate func better() {
  good()
}
}

=== file: Some+Bar.swift

extension Some {
  internal func bar() {
  foo()
  }
  classprivate func good() {
  better()
   }
}

=== any other file (same module)

class Other {
func x() {
let some = Some()

some.foo() // ** UNWANTED!!

some.better() // error.  ** WANTED!
}
}

I do not want to audit the class Other when I make a change to "foo" or
"bar", which are essentially "private" and only made "internal" because of
the language limitation in regards to "private" vs "multi-file class" issue.


> What does marking a method as “specialprivate” (my made up name for this
> new access level) tell clients about who can use it or how it can be used?
>

it tells them: "you can't use this, unless you are writing an extension to
this class or making changes to this class itself"

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


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Adam Kemp via swift-evolution


> On Oct 30, 2017, at 10:57 AM, Mike Kluev  wrote:
> 
> On 30 October 2017 at 17:22, Adam Kemp  > wrote:
> 
> The goal isn’t to entirely avoid having to audit any code while making a 
> change. The goal is to allow you to reason about which code you would have to 
> audit. A new access level should lead to a new bucket of code that needs to 
> be audited, but none of the proposals here would do that. They’re all 
> equivalent to existing access levels.
> 
> the new bucket would be "class and all of its extensions be them in the same 
> file or in different files”.

That’s not a new bucket. It is equivalent to either internal or public, 
depending on whether you want to extend this beyond the module boundary. The 
set of code you would have to audit is the same.

> 
> back to your example with the locked door and the keys on the doorstep, i can 
> violate "protected" in C++:
> 
> developer 1:
> class Base { protected void foo(); }
> 
> developer 2:
> class Derived: Base { public void not_so_protected_foo() { foo() }
> 
> but that doesn't mean that "protected" in C++ shall be ditched!

In terms of reasoning about code that might break, protected is equivalent to 
public. The only advantage to protected over public is that it tells clients 
how to properly use it.

What does marking a method as “specialprivate” (my made up name for this new 
access level) tell clients about who can use it or how it can be used?

> 
> this is similar to what you said before about writing an extension and 
> exposing the private functionality as public violating protection.
> 
> Mike
> 

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


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Mike Kluev via swift-evolution
On 30 October 2017 at 17:22, Adam Kemp  wrote:

>
> The goal isn’t to entirely avoid having to audit any code while making a
> change. The goal is to allow you to reason about which code you would have
> to audit. A new access level should lead to a new bucket of code that needs
> to be audited, but none of the proposals here would do that. They’re all
> equivalent to existing access levels.
>

the new bucket would be "class and all of its extensions be them in the
same file or in different files".

back to your example with the locked door and the keys on the doorstep, i
can violate "protected" in C++:

developer 1:
class Base { protected void foo(); }

developer 2:
class Derived: Base { public void not_so_protected_foo() { foo() }

but that doesn't mean that "protected" in C++ shall be ditched!

this is similar to what you said before about writing an extension and
exposing the private functionality as public violating protection.

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


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Adam Kemp via swift-evolution

> On Oct 30, 2017, at 10:10 AM, Mike Kluev  wrote:
> 
> On 30 October 2017 at 16:34, Adam Kemp  > wrote:
> 
> I didn’t mean “no, you can’t do that”. You can if you want to. What I meant 
> was “no, I’m not suggesting that you should do that”. I don’t think it’s 
> necessary.
> 
> as you said before the benefit of keeping private things private is 
> minimizing the amount of code that can break once you change a variable. if 
> it's "internal" - the whole module must be checked. if it is "internal" 
> rather than "private”:
> it is done because otherwise i'd have to keep the (big) class in a single file

The goal isn’t to entirely avoid having to audit any code while making a 
change. The goal is to allow you to reason about which code you would have to 
audit. A new access level should lead to a new bucket of code that needs to be 
audited, but none of the proposals here would do that. They’re all equivalent 
to existing access levels.

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


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Mike Kluev via swift-evolution
sorry, hit "Sent" too early

On 30 October 2017 at 16:34, Adam Kemp  wrote:

>
> I didn’t mean “no, you can’t do that”. You can if you want to. What I
> meant was “no, I’m not suggesting that you should do that”. I don’t think
> it’s necessary.
>

as you said before the benefit of keeping private things private is
minimizing the amount of code that can break once you change a variable. if
it's "internal" - the whole module must be checked. if it is "internal"
rather than "private":

- it is done because otherwise i'd have to keep the (big) class in a single
file
- shows the limitation in the language in regards to one-file-class vs
multi-file-class
- forces me to use one module per file if I want to mimic the "private"
keyword as close as possible
- or forces me to keep my class in a single file.

> Which other language has an access level like the one being proposed?

i am not aware of such a language. C++'s "private" comes close as it can be
used in multiple files but then C++ doesn't have extensions. C++
"protected" comes close for something I can use in subclasses.

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


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Mike Kluev via swift-evolution
On 30 October 2017 at 16:34, Adam Kemp  wrote:

>
> I didn’t mean “no, you can’t do that”. You can if you want to. What I
> meant was “no, I’m not suggesting that you should do that”. I don’t think
> it’s necessary.
>

as you said before the benefit of keeping private things private is
minimizing the amount of code that can break once you change a variable. if
it's "internal" - the whole module must be checked. if it is "internal"
rather than "private":
it is done because otherwise i'd have to keep the (big) class in a single
file



> Which other language has an access level like the one being proposed?
>
>
> this:
>
> SingleFileClass1.swift // with bunch of "privates" inside
>
> SingleFileClass2.swift // with bunch of "privates" inside
>
> SingleFileClass3.swift // with bunch of "privates" inside
>
> is equivalent to this:
>
> Module solely for Class1
>Class1.swift // with bunch of "internals inside
>Class1+Extension.swift // with bunch of "internals" inside
>
> Module solely for Class2
>Class2.swift // with bunch of "internals" inside
>Class2+Extension.swift // with bunch of "internals" inside
>
> Module solely for Class3
>Class3.swift  // with bunch of "internals" inside
>Class3+Extension.swift // with bunch of "internals" inside
>
>
> still "no" ?
>
> i mean, it's fine (although a bit odd) that a mere change from a
> single-file to a multi-file class leads to such drastic consequences.
> different to what i saw before. but I can adapt of course.
>
> Either way the answer is basically the same: don’t obfuscate the effective
>> access level and pretend you’re being strict when you’re really not. It’s
>> like putting a lock on the door with the key hanging from the doorknob. You
>> may as well just keep it unlocked.
>>
>>
> nice analogy :-)
>
> Mike
>
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Adam Kemp via swift-evolution

> On Oct 30, 2017, at 5:34 AM, Mike Kluev  wrote:
> 
> On 30 October 2017 at 07:30, Adam Kemp  > wrote:
> 
> No. There are two reasonable options:
> 
> 1. Make it public. If it’s needed outside the module then this is an accurate 
> description of its access level. 
> 
> 2. Make it internal and accept that any code in the same module can access 
> it. Again, that is effectively what your proposed scope allows anyway so 
> internal is an accurate description of its actual access level. Call it what 
> it is.
> 
> 
> Adam, i fail to see why you say "No" to "one module per class approach" if 
> the goal is to make the individual multi-file classes as isolated as possible 
> (i.e. not see each other "internal" stuff). which (this goal) is considered 
> the "way to go" approach in other languages and the "default" behaviour.

I didn’t mean “no, you can’t do that”. You can if you want to. What I meant was 
“no, I’m not suggesting that you should do that”. I don’t think it’s necessary.

Which other language has an access level like the one being proposed?

> 
> this:
> 
> SingleFileClass1.swift // with bunch of "privates" inside
> 
> SingleFileClass2.swift // with bunch of "privates" inside
> 
> SingleFileClass3.swift // with bunch of "privates" inside
> 
> is equivalent to this:
> 
> Module solely for Class1
>Class1.swift // with bunch of "internals inside
>Class1+Extension.swift // with bunch of "internals" inside
>
> Module solely for Class2
>Class2.swift // with bunch of "internals" inside
>Class2+Extension.swift // with bunch of "internals" inside  
> 
> Module solely for Class3
>Class3.swift  // with bunch of "internals" inside
>Class3+Extension.swift // with bunch of "internals" inside
>
> 
> still "no" ?
> 
> i mean, it's fine (although a bit odd) that a mere change from a single-file 
> to a multi-file class leads to such drastic consequences. different to what i 
> saw before. but I can adapt of course.
> 
> Either way the answer is basically the same: don’t obfuscate the effective 
> access level and pretend you’re being strict when you’re really not. It’s 
> like putting a lock on the door with the key hanging from the doorknob. You 
> may as well just keep it unlocked. 
> 
> 
> nice analogy :-)
> 
> Mike
> 

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


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread C. Keith Ray via swift-evolution
Access levels are not a security mechanism. You have to trust your (fellow) 
programmers. Lots of good software has been created in Smalltalk and other 
languages without "private" access levels.

--
C. Keith Ray

* https://leanpub.com/wepntk <- buy my book?
* http://www.thirdfoundationsw.com/keith_ray_resume_2014_long.pdf
* http://agilesolutionspace.blogspot.com/

> On Oct 30, 2017, at 5:34 AM, Mike Kluev via swift-evolution 
>  wrote:
> 
>> On 30 October 2017 at 07:30, Adam Kemp  wrote:
>> 
>> No. There are two reasonable options:
>> 
>> 1. Make it public. If it’s needed outside the module then this is an 
>> accurate description of its access level. 
>> 
>> 2. Make it internal and accept that any code in the same module can access 
>> it. Again, that is effectively what your proposed scope allows anyway so 
>> internal is an accurate description of its actual access level. Call it what 
>> it is.
>> 
> 
> Adam, i fail to see why you say "No" to "one module per class approach" if 
> the goal is to make the individual multi-file classes as isolated as possible 
> (i.e. not see each other "internal" stuff). which (this goal) is considered 
> the "way to go" approach in other languages and the "default" behaviour.
> 
> this:
> 
> SingleFileClass1.swift // with bunch of "privates" inside
> 
> SingleFileClass2.swift // with bunch of "privates" inside
> 
> SingleFileClass3.swift // with bunch of "privates" inside
> 
> is equivalent to this:
> 
> Module solely for Class1
>Class1.swift // with bunch of "internals inside
>Class1+Extension.swift // with bunch of "internals" inside
>
> Module solely for Class2
>Class2.swift // with bunch of "internals" inside
>Class2+Extension.swift // with bunch of "internals" inside  
> 
> Module solely for Class3
>Class3.swift  // with bunch of "internals" inside
>Class3+Extension.swift // with bunch of "internals" inside
>
> 
> still "no" ?
> 
> i mean, it's fine (although a bit odd) that a mere change from a single-file 
> to a multi-file class leads to such drastic consequences. different to what i 
> saw before. but I can adapt of course.
> 
>> Either way the answer is basically the same: don’t obfuscate the effective 
>> access level and pretend you’re being strict when you’re really not. It’s 
>> like putting a lock on the door with the key hanging from the doorknob. You 
>> may as well just keep it unlocked. 
>> 
> 
> nice analogy :-)
> 
> Mike
> 
> ___
> 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] [Discussion] Inheritance from associated types / protocols as broader templates

2017-10-30 Thread Mike Kasianowicz via swift-evolution
I often find myself running up against errors like "Inheritance from 
non-protocol, non-class type”.

Here’s a contrived example.

public protocol NoiseMechanism : class {
func makeNoise()
}

public protocol Animal {
associatedtype NoiseMaker: NoiseMechanism

static var numberOfLegs: Int { get }
}

open class AnimalWrapper : A.NoiseMaker {
}


The benefit is that a consuming developer can inject types using one parameter 
and result in a robust type ecosystem.

This ties into my previous request to have non-class constraints (enums, 
structs) on protocols and in where clauses. I’m very interested in using 
protocols to enforce architectural decisions.

What do people generally think about this?  Is a protocol the right construct? 
Is this something that could be possible in the future, or completely off the 
table due to complexity, or just not addressed due to low priority?___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Mike Kluev via swift-evolution
On 30 October 2017 at 07:30, Adam Kemp  wrote:

>
> No. There are two reasonable options:
>
> 1. Make it public. If it’s needed outside the module then this is an
> accurate description of its access level.
>
> 2. Make it internal and accept that any code in the same module can access
> it. Again, that is effectively what your proposed scope allows anyway so
> internal is an accurate description of its actual access level. Call it
> what it is.
>
>
Adam, i fail to see why you say "No" to "one module per class approach" if
the goal is to make the individual multi-file classes as isolated as
possible (i.e. not see each other "internal" stuff). which (this goal) is
considered the "way to go" approach in other languages and the "default"
behaviour.

this:

SingleFileClass1.swift // with bunch of "privates" inside

SingleFileClass2.swift // with bunch of "privates" inside

SingleFileClass3.swift // with bunch of "privates" inside

is equivalent to this:

Module solely for Class1
   Class1.swift // with bunch of "internals inside
   Class1+Extension.swift // with bunch of "internals" inside

Module solely for Class2
   Class2.swift // with bunch of "internals" inside
   Class2+Extension.swift // with bunch of "internals" inside

Module solely for Class3
   Class3.swift  // with bunch of "internals" inside
   Class3+Extension.swift // with bunch of "internals" inside


still "no" ?

i mean, it's fine (although a bit odd) that a mere change from a
single-file to a multi-file class leads to such drastic consequences.
different to what i saw before. but I can adapt of course.

Either way the answer is basically the same: don’t obfuscate the effective
> access level and pretend you’re being strict when you’re really not. It’s
> like putting a lock on the door with the key hanging from the doorknob. You
> may as well just keep it unlocked.
>
>
nice analogy :-)

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


Re: [swift-evolution] classprivate protection level?

2017-10-30 Thread Adam Kemp via swift-evolution


> On Oct 29, 2017, at 9:22 PM, Mike Kluev  wrote:
> 
> Module1
> 
> Class A in it's own file
> extension A in it's own file
> 
> Class B in it's own file
> extension B in it's own file
> 
> Class C in it's own file
> extension C in it's own file
> 
> Module 2
> 
> 
> obviously i do not want guys from team B and C accessing anything "team A 
> private".

Then your proposal cannot help you accomplish that goal. If any extension of 
class A can access a method then someone writing code in the same file as B or 
C can write an extension of class A and expose it to other code in the same 
file as B or C. That means when you are making a change to that method you have 
to assume that there may be code relying on it, and you have to audit that code.

It’s worse than that, though. If that method is accessible even to extensions 
in other modules then that means any external client of this module could also 
rely on that behavior, and that means you cannot safely change it at all. You 
have effectively made it public. You have lost all control. It is no longer 
encapsulated at all.

When you choose an access level you are deciding which code you are allowing to 
depend on it, and thus which code you will have to fix if you change it. If a 
change might break any client of the whole module then it’s public. You’re only 
fooling yourself if you call it something else. 

> 
> is my understanding of your words then correct that you suggest to have this:
> 
> Module1
> 
> Class A in it's own file
> extension A in it's own file
> 
> Module2
> 
> Class B in it's own file
> extension B in it's own file
> 
> Module3
> 
> Class C in it's own file
> extension C in it's own file
> 
> Module 4
> 

No. There are two reasonable options:

1. Make it public. If it’s needed outside the module then this is an accurate 
description of its access level. 

2. Make it internal and accept that any code in the same module can access it. 
Again, that is effectively what your proposed scope allows anyway so internal 
is an accurate description of its actual access level. Call it what it is.

Either way the answer is basically the same: don’t obfuscate the effective 
access level and pretend you’re being strict when you’re really not. It’s like 
putting a lock on the door with the key hanging from the doorknob. You may as 
well just keep it unlocked. 

> 
> 
> 
>> On 30 October 2017 at 04:04, Adam Kemp  wrote:
>> Access levels exist for encapsulation. They don’t mean anything unless they 
>> actually allow you to reason about which code can break if you make a 
>> change. Given that, here is how each existing access level is useful:
>> 
>> Public means a change could break any code. 
>> 
>> Internal means only code in the module can break so you can audit all 
>> usages in that module and fix as needed.
>> 
>> File private means only code within the file can break so you only have 
>> to audit the one file.
>> 
>> Private means only code within the class or extensions in the same file 
>> can break so you only have to audit part of that one file.
>> 
>> What would a proposed new access level mean for which code has to be audited 
>> when making a change?
>> 
>> If any extension can access something even across modules then that 
>> makes it the same as public. You can’t make any change without risking 
>> breaking a client.
>> 
>> If any extension can access something within the same module then it’s 
>> the same as internal. You have to audit the whole module.
>> 
>> If your new access level doesn’t make a new bucket for what code to audit 
>> then it’s not adding any value.
>> 
>>> On Oct 29, 2017, at 8:40 PM, Mike Kluev  wrote:
>>> 
 On 30 October 2017 at 02:54, Adam Kemp  wrote:
 
 That was my original point. This is what internal does. We don’t need any 
 new access levels for extensions. Internal solves these use cases. Code in 
 the same module can be maintained in lockstep so you can make things 
 internal as needed for extensions. Anything beyond that is effectively 
 indistinguishable from public so just call it that. 
 
>>> 
>>> if I have N big classes,  each split across M files to keep size 
>>> manageable, do I need to have N different modules if i want to achieve a 
>>> good separation between classes? (same level of protection that private 
>>> gives for a class that fits in a single file) i.e. one module per one class?
>>> 
>>> Mike
>>> 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution