Re: [swift-evolution] No disjunctions in type constraints: why?

2018-01-17 Thread Robert Widmann via swift-evolution
If you replace “conjunction” by “O(n) search with early-exit on failure” and 
“disjunction” by just “O(n) search”, you’ll see why this can lead to 
computationally painful systems of constraints.  Each disjunctive constraint 
may further contain or create disjunctions ad nauseum, each time incrementing 
the exponent in the worst-case time it takes to solve the system.  Introduction 
of disjunction into an already complex system (say, one that supports 
constrained parametric polymorphism and subtyping AND disjunctions through 
overloads) makes an already difficult problem even harder.

~Robert Widmann 

2018/01/13 4:45、Daryle Walker via swift-evolution 
のメール:

> From 
> .
> 
> Maybe I’m not up on my Type Theory, but why should type constraint 
> disjunctions be banned?
> 
> — 
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com 
> 
> ___
> 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] [swift-dev] Re-pitch: Deriving collections of enum cases

2018-01-08 Thread Robert Widmann via swift-evolution


~Robert Widmann 

2017/12/31 11:02、Karl Wagner via swift-evolution 
のメール:

> 
> 
>> On 31. Dec 2017, at 00:12, Jacob Bandes-Storch via swift-evolution 
>>  wrote:
>> 
>> Sorry for the delay. I've just updated the proposal text to incorporate 
>> various changes, some contributed by others.
>> 
>> https://github.com/jtbandes/swift-evolution/blob/case-enumerable/proposals/-derived-collection-of-enum-cases.md
>> 
>> Robert's implementation is a good start, but will need to be updated to 
>> match the naming choice in the final proposal, and to use associatedtype.
> 
> 
> Looks good, but I have two questions:
> 
> 1) What is the exact semantic meaning of ValueEnumerable? Does it somehow 
> imply an enum? Or is it simply an abstraction for any type with a “fixed, 
> finite set of [values]”?

The exact meaning of a synthesized conformance to ValueEnumerable is

- The type is an enum
- That enum is not @objc
- That enum is composed entirely of cases that have no associated values
- That enum is defined in the module declaring the synthesized conformance (ie 
no extensions - same as Equatable and Hashable)

The exact meaning of a general conformance is

- The type has a finite number of possible values inhabiting it

As you note, integral types and Bool and some enums that fall outside the scope 
of the synthesis requirements fit this mold quite nicely.  We do not include 
them in the proposal partially to keep things simple, partially because we’d be 
stepping on Range’s toes, and partially because synthesis for structs is tricky 
in the general case.  If deemed particularly useful in the future, these 
conformance can be added.

> 
> 2) Is the order of values in the Collection generally meaningful, or not? If 
> not, would it be reasonable for types which conform to Comparable to always 
> return a sorted Collection? Or should we manually sort it with 
> “MyEnum.allValues.sorted()”?

The interface for the protocol makes no ordering guarantees, but the 
synthesized conformance uses source-order because that’s currently the way the 
runtime metadata (which will become ABI) is implemented.  It is up to authors 
to document the ordering stability of the value collection or to let the 
compiler handle it for them.

~Robert Widmann

> 
> - Karl
> 
>> 
>>> On Fri, Dec 8, 2017 at 9:19 PM, Step Christopher 
>>>  wrote:
>>> Has this stalled out again? I would like to help with the proposal and even 
>>> attempt implementation. 
>>> 
>>> I also need to catch up on the resilient discussion regarding enum case 
>>> ordering. 
>>> 
 On Nov 14, 2017, at 10:50 PM, Jacob Bandes-Storch via swift-evolution 
  wrote:
 
 
 
 Jacob Bandes-Storch
 
 On Tue, Nov 14, 2017 at 9:06 PM, Brent Royal-Gordon 
  wrote:
>>> On Nov 14, 2017, at 5:21 PM, Xiaodi Wu  wrote:
>>> 
>>> 1. It must be possible to easily access the count of values, and to 
>>> access any particular value using contiguous `Int` indices. This could 
>>> be achieved either by directly accessing elements in the list of values 
>>> through an Int subscript, or by constructing an Array from the list of 
>>> values.
>>> 
>>> 2. It must be possible to control the order of values in the list of 
>>> values, either by using source order or through some other simple, 
>>> straightforward mechanism.
>>  
>> OK, first of all, nowhere in the proposal text are these requirements 
>> stated as part of the use case. You're free to put forward new use 
>> cases, but here I am trying to design the most elegant way to fulfill a 
>> stated need and you're telling me that it's something other than what's 
>> written.
> 
> Honestly, re-reading the proposal, it never cites a fully-formed use 
> case. Instead, it cites several blog posts, Stack Overflow questions, and 
> small code samples without digging in to the underlying reasons why 
> developers are doing what they're doing. Most of the people discussing it 
> so far seem to have had a tacit understanding that we wanted roughly 
> Array-like access, but we haven't explicitly dug into which properties of 
> an Array are important.
> 
> (If anyone involved feels like they had a different understanding of the 
> use case, please speak up.)
> 
> I think this is a place where the proposal can be improved, and I'm 
> willing to do some writing to improve it.
 
 For the record, I would be happy to add co-authors (or even relinquish 
 authorship entirely—I don't really care whose name is on this, it just 
 needs to happen!) if you or anyone else has improved wording, motivation, 
 justification, etc. to contribute.
 ___
 swift-evolution mailing list
 

Re: [swift-evolution] [Idea] [Pitch] Add `match` statement as `switch`-like syntax alternative to `if case` pattern matching

2017-11-18 Thread Robert Widmann via swift-evolution
In regards to the problem in the root (using if-cases to do membership tests on 
option sets), the code given there involving thinking of the OptionSet as a 
sequence and iterating over it makes this far less likely to happen.  I think 
this is a pattern that doesn't need syntax, it needs stdlib support at most.  
Perhaps an extension to OptionSet when the RawValue is known to be a sized 
integral type that does just that would clean up here.

~Robert Widmann 

2017/11/18 17:25、Benjamin G via swift-evolution のメール:

> I think because it's not immediately obvious with multiple if statement, that 
> they all try to compare the same expression to different patterns.
> 
> match exp {
> case 1
> case 2
> }
> vs
> if case 1 = exp
> if case 2 = anotherexp 
> 
> 
>> On Sat, Nov 18, 2017 at 10:43 PM, Xiaodi Wu via swift-evolution 
>>  wrote:
>>> On Sat, Nov 18, 2017 at 3:12 PM, Peter Kamb  wrote:
>> 
>>> A high bar for new syntax is fair and expected, and by posting I was hoping 
>>> to maybe find an alternative in the comments here.
>>> 
>>> But AFAIK there's currently no ability in Swift to:
>>> 
>>> "Evaluate a *single* control expression against all of these patterns, and 
>>> execute any and all cases that match"
>>> 
>>> Multiple `if-case` statements, each re-stating the control expression, are 
>>> ok.
>>> 
>>> But that's definitely not as clear or concise as a switch-like construct 
>>> with the single control expression at the top. Or perhaps some other 
>>> alternative such as the mentioned `continue` or somehow enumerating a set 
>>> of cases.
>> 
>> You're simply restating your proposed new syntax as the thing that's 
>> missing. But what is the use case that motivates this construct? In what way 
>> are multiple if-case statements "not as clear"?
>> 
 On Sat, Nov 18, 2017 at 11:18 AM, Xiaodi Wu  wrote:
 Robert is quite right--I'm not sure what we're designing for here. There's 
 a very high bar for introducing new syntax and a distaste for the existing 
 syntax is not a motivating use case.
 
 
> On Sat, Nov 18, 2017 at 12:53 PM, Kevin Nattinger via swift-evolution 
>  wrote:
> There have been earlier suggestions for an alternative to `fallthrough` 
> that would continue matching cases; I think that is much more likely to 
> get support than a whole new construct with only a subtle difference from 
> an existing one—would that be an acceptable alternative to you?
> 
> > On Nov 17, 2017, at 12:06 PM, Peter Kamb via swift-evolution 
> >  wrote:
> >
> > ## Title
> >
> > Add `match` statement as `switch`-like syntax alternative to `if case` 
> > pattern matching
> >
> > ## Summary:
> >
> > The syntax of the `switch` statement is familiar, succinct, elegant, 
> > and understandable. Swift pattern-matching tutorials use `switch` 
> > statements almost exclusively, with small sections at the end for 
> > alternatives such as `if case`.
> >
> > However, the `switch` statement has several unique behaviors unrelated 
> > to pattern matching. Namely:
> >
> >  - Only the *first* matching case is executed. Subsequent matching 
> > cases are not executed.
> >  - `default:` case is required, even for expressions where a default 
> > case does not make sense.
> >
> > These behaviors prevent `switch` from being used as a generic 
> > match-patterns-against-a-single-expression statement.
> >
> > Swift should contain an equally-good pattern-matching statement that 
> > does not limit itself single-branch switching.
> >
> > ## Pitch:
> >
> > Add a `match` statement with the same elegant syntax as the `switch` 
> > statement, but without any of the "branch switching" baggage.
> >
> > ```
> > match someValue {
> > case patternOne:
> > always executed if pattern matches
> > case patternTwo:
> > always executed if pattern matches
> > }
> > ```
> >
> > The match statement would allow a single value to be filtered through 
> > *multiple* cases of pattern-matching evaluation.
> >
> > ## Example:
> >
> > ```
> > struct TextFlags: OptionSet {
> > let rawValue: Int
> > static let italics = TextFlags(rawValue: 1 << 1)
> > static let bold= TextFlags(rawValue: 1 << 2)
> > }
> >
> > let textFlags: TextFlags = [.italics, .bold]
> >
> >
> >
> > // SWITCH STATEMENT
> > switch textFlags {
> > case let x where x.contains(.italics):
> > print("italics")
> > case let x where x.contains(.bold):
> > print("bold")
> > default:
> > print("forced to include a default case")
> > }
> > // prints "italics"
> > // Does NOT print "bold", 

Re: [swift-evolution] [Idea] [Pitch] Add `match` statement as `switch`-like syntax alternative to `if case` pattern matching

2017-11-18 Thread Robert Widmann via swift-evolution

> On Nov 18, 2017, at 4:42 AM, Peter Kamb  wrote:
> 
> Thanks for the review.
> 
> Motivation is essentially to provide a low-friction way to write `if case / 
> if case / if case` statements that are all matching on the same expression, 
> much in the same way that `switch` offers a way to write `if / else if / 
> else` statements against the same expression.

That much I understand, but there’s no motivation as to why this kind of change 
needs to occur over a line of if-case statements.  There isn’t anything in the 
pitch that demonstrates friction outside of a personal distaste for the syntax.

> 
>  > > Only the *first* matching case is executed. Subsequent matching cases 
> are not executed.
>  > This is not unrelated to pattern matching, this is the expected behavior 
> of every pattern matching algorithm.
>  
> By that I meant that a string of `if case / if case / if case` statements, 
> each individually matching against the same expression, would match and 
> execute all 3 cases. A `switch` using the same 3 cases would execute only the 
> first matching case. I took the "only first case" behavior to be a property 
> of the *switch*, not of "pattern matching" in general? But perhaps I'm using 
> the wrong terminology.
>  
>  > > Allow filtering a single object through *multiple* cases of pattern 
> matching, executing *all* cases that match.
>  > Again, this is not pattern matching.
> 
> A switch can have multiple cases that "would" match and execute, if you were 
> to comment out the successful case above them. Why would a hypothetical 
> statement that executed *all* matching cases, rather than just the first 
> case, not be pattern matching? It wouldn't be a `switch`, for sure, but it 
> seems like it would be just as much "pattern matching" as an `if-case`.

It is not pattern matching because it violates minimality - and we have a 
warning today when you write switches of overlapping patterns.  Consider the 
semantics of pattern matching in the context of a tree - but it just so happens 
the nodes of this tree are your patterns and the branches, actual branches 
where control flow splits along the case-matrix.  The goal is not to execute a 
find-all, the goal is to execute a find - exactly like a regular expression.  

> 
>  > This is not boilerplate!
> 
> An `if case / if case` pair would not have the same concept of a shared 
> `else/default` case used by a `switch` or `if/else`, which is why I said it 
> would not be needed. `if-case` does not require an else/default. (Perhaps 
> boilerplate was the wrong word, and I definitely didn't mean to suggest that 
> switches should no longer require `default:`).

You misunderstand me.  This is the same problem as the one I brought up before: 
You are subject to the halting problem in the general case. The catch-all 
clause isn’t just noise, it’s a fundamental necessity to guarantee sound 
semantics for this particular class of switch statements that, according to a 
fundamental barrier in computer science, cannot be checked for exhaustiveness.

On top of that, we cannot allow you to write an uncovered switch statement full 
of expression patterns because you would most-assuredly not handle all possible 
cases (suppose I extend your OptionSet with a new bit-pattern in a different 
module - your code will miscompile).

> 
> On Sat, Nov 18, 2017 at 12:19 AM, Robert Widmann  > wrote:
> Having spent a lot of time with ‘switch’, I don’t understand any of the 
> motivations or corresponding justifications for this idea.  Comments inline:
> 
> ~Robert Widmann 
> 
> 2017/11/17 15:06、Peter Kamb via swift-evolution  >のメール:
> 
>> ## Title
>> 
>> Add `match` statement as `switch`-like syntax alternative to `if case` 
>> pattern matching
>> 
>> ## Summary:
>> 
>> The syntax of the `switch` statement is familiar, succinct, elegant, and 
>> understandable. Swift pattern-matching tutorials use `switch` statements 
>> almost exclusively, with small sections at the end for alternatives such as 
>> `if case`.
>> 
>> However, the `switch` statement has several unique behaviors unrelated to 
>> pattern matching. Namely:  
> 
> 
>> 
>>  - Only the *first* matching case is executed. Subsequent matching cases are 
>> not executed.
> 
> This is not unrelated to pattern matching, this is the expected behavior of 
> every pattern matching algorithm.  The intent is to compile a switch-case 
> tree down to (conceptually) a (hopefully minimal) if-else tree.  You may be 
> thinking of the behavior of switch in C and C-likes which is most certainly 
> not pattern matching and includes behavior Swift has explicitly chosen to 
> avoid like implicit fallthroughs.
> 
>>  - `default:` case is required, even for expressions where a default case 
>> does not make sense.
> 
> Expression patterns may look to be covered “at first glance”, but the 

Re: [swift-evolution] [Idea] [Pitch] Add `match` statement as `switch`-like syntax alternative to `if case` pattern matching

2017-11-18 Thread Robert Widmann via swift-evolution
Having spent a lot of time with ‘switch’, I don’t understand any of the 
motivations or corresponding justifications for this idea.  Comments inline:

~Robert Widmann 

2017/11/17 15:06、Peter Kamb via swift-evolution のメール:

> ## Title
> 
> Add `match` statement as `switch`-like syntax alternative to `if case` 
> pattern matching
> 
> ## Summary:
> 
> The syntax of the `switch` statement is familiar, succinct, elegant, and 
> understandable. Swift pattern-matching tutorials use `switch` statements 
> almost exclusively, with small sections at the end for alternatives such as 
> `if case`.
> 
> However, the `switch` statement has several unique behaviors unrelated to 
> pattern matching. Namely:  


> 
>  - Only the *first* matching case is executed. Subsequent matching cases are 
> not executed.

This is not unrelated to pattern matching, this is the expected behavior of 
every pattern matching algorithm.  The intent is to compile a switch-case tree 
down to (conceptually) a (hopefully minimal) if-else tree.  You may be thinking 
of the behavior of switch in C and C-likes which is most certainly not pattern 
matching and includes behavior Swift has explicitly chosen to avoid like 
implicit fallthroughs.

>  - `default:` case is required, even for expressions where a default case 
> does not make sense.

Expression patterns may look to be covered “at first glance”, but the analysis 
required to prove that is equivalent to solving the halting problem in the 
general case.  Further, your proposed idea has absolutely nothing to do with 
this.

> 
> These behaviors prevent `switch` from being used as a generic 
> match-patterns-against-a-single-expression statement.
> 
> Swift should contain an equally-good pattern-matching statement that does not 
> limit itself single-branch switching.
> 
> ## Pitch:
> 
> Add a `match` statement with the same elegant syntax as the `switch` 
> statement, but without any of the "branch switching" baggage.
> 
> ```
> match someValue {
> case patternOne:
> always executed if pattern matches
> case patternTwo:
> always executed if pattern matches
> }
> ```
> 
> The match statement would allow a single value to be filtered through 
> *multiple* cases of pattern-matching evaluation.
> 
> ## Example:
> 
> ```
> struct TextFlags: OptionSet {
> let rawValue: Int
> static let italics = TextFlags(rawValue: 1 << 1)
> static let bold= TextFlags(rawValue: 1 << 2)
> }
> 
> let textFlags: TextFlags = [.italics, .bold]
> 
> 
> 
> // SWITCH STATEMENT
> switch textFlags {
> case let x where x.contains(.italics):
> print("italics")
> case let x where x.contains(.bold):
> print("bold")
> default:
> print("forced to include a default case")
> }
> // prints "italics"
> // Does NOT print "bold", despite .bold being set.
> 
> 
> 
> // MATCH STATEMENT
> match textFlags {
> case let x where x.contains(.italics):
> print("italics")
> case let x where x.contains(.bold):
> print("bold")
> }
> // prints "italics"
> // prints "bold"
> ```
> 
> ## Enum vs. OptionSet
> 
> The basic difference between `switch` and `match` is the same conceptual 
> difference between `Emum` and an `OptionSet` bitmask.
> 
> `switch` is essentially designed for enums: switching to a single logical 
> branch based on the single distinct case represented by the enum.
> 
> `match` would be designed for OptionSet bitmasks and similar constructs. 
> Executing behavior for *any and all* of the following cases and patterns that 
> match.
> 
> The programmer would choose between `switch` or `match` based on the goal of 
> the pattern matching. For example, pattern matching a String. `switch` would 
> be appropriate for evaluating a String that represents the rawValue of an 
> enum. But `match` would be more appropriate for evaluating a single input 
> String against multiple unrelated-to-each-other regexes.
> 
> ## Existing Alternatives
> 
> `switch` cannot be used to match multiple cases. There are several ways "test 
> a value against multiple patterns, executing behavior for each pattern that 
> matches", but none are as elegant and understandable as the switch statement 
> syntax.
> 
> Example using a string of independent `if case` statements:
> 
> ```
> if case let x = textFlags, x.contains(.italics) {
> print("italics")
> }
> 
> if case let x = textFlags, x.contains(.bold) {
> print("bold")
> }
> ```
> 
> ## `match` statement benefits:
> 
>  - Allow filtering a single object through *multiple* cases of pattern 
> matching, executing *all* cases that match.

Again, this is not pattern matching.

> 
>  - A syntax that exactly aligns with the familiar, succinct, elegant, and 
> understandable `switch` syntax.

A syntax that duplicates the existing if-case construct which, I should note, 
takes the same number of lines and roughly the same number of columns to 
express as your match.  Even less, considering you unwrap in the if-case to 
exaggerate the 

Re: [swift-evolution] [Pitch] Improving capturing semantics of local functions

2017-11-15 Thread Robert Widmann via swift-evolution


~Robert Widmann 

2017/11/14 22:02、Matthew Johnson via swift-evolution 
のメール:

> 
> 
> Sent from my iPhone
> 
>> On Nov 14, 2017, at 6:56 PM, Howard Lovatt via swift-evolution 
>>  wrote:
>> 
>> Having read all the arguments for what to add to local functions it still 
>> strikes me as a poor use of engineering resources to fix them (though I do 
>> agree they have problems). A better use of resources would be:
>> 
>>   1. Deprecate local functions.
>>   2. Allow closures when assigned to a function type to be:
>>   2a. Recursive.
>>   2b. Annotatable with:
>> 2bi.  @inline
>> 2bii. @escaping
>>   2c. Generic.
>> 
>> That would be a similar engineering effort and give a better short term 
>> result of better closures which would be much more widely applicable as well 
>> as addressing the issues with local functions.
> 
> I believe generic closures would require adding higher rank types to Swift.  
> That would be pretty cool but I suspect the engineering effort is at least an 
> order of magnitude greater than the changes discussed in this thread.

100% correct. Slava raises good points about implementation, I’ll raise one 
about semantics:

Without sufficient restrictions on this kind of polymorphism, type checking 
will become significantly more difficult for little corresponding benefit.  
Enabling the formation of polymorphic types just because you’re near an arrow 
means all sorts of fun things now get to happen

let f = { x in { y in y } }

This program is illegal without a type signature, but still typeable in that 
Swift will try to look for bindings to the tn’s in this signature

f :  (T0) -> (T1) -> T1

This is good - this is the most general unifier for this expression promised to 
us by the “Hindley-Milner-like” label we have in the type checker docs.

Given even rank-2 types, the most general unifier is (ideally) now 

f :  (T0) -> ( (T1) -> T1)

Which is significant because despite an obvious isomorphism, the former is not 
a specialization of the latter.  It is a completely separate polytype that 
would require additional structural rules to recover the correct behavior.  
This can also block inference or generate counterintuitive unifiers if we’re 
forced to e.g. unify nested polytypes against each other.

~Robert Widmann

> 
>> 
>> It also gives a better long term result of not having to maintain local 
>> functions.
>>   
>> 
>>   -- Howard.
>> 
>>> On 15 November 2017 at 09:08, Alex Lynch via swift-evolution 
>>>  wrote:
>>> The inference algebra just suggested was enjoyable to read, but is still a 
>>> new syntax. Which is interesting and deserving of its own proposal. The 
>>> purpose of this proposal is simply to introduce the existing capture syntax 
>>> to local functions. Thanks to everyone's feedback pointing out that the 
>>> `self` reference analysis is a deeper question than initially realized. 
>>> 
>>> Alex
>>> 
> On Tue, Nov 14, 2017 at 4:36 PM, Mike Kluev via swift-evolution 
>  wrote:
> On 14 November 2017 at 21:02, David Hart  wrote:
 
> 
> 
> I’d be very hesitant to introduce this syntax:
> 
> it’s new syntax, so it comes with a complexity tax (it isn’t naturally 
> obvious what it means for a func to be weak)
> it’s only sugar for the capture of self
 
 it might cover well over 90% of use cases (by my "pessimistic" 
 estimate)... if someone has a quick way to scan and analyse, say, github 
 swift sources we may even know that current percentage number of real life 
 usage.
> it doesn’t transpose well to local closures
 
 the last one - maybe not. follow me:
 
 let closure = { [weak self, bar] in ... }
 
 which today can be written as: 
 
 let closure = { [weak self, bar] () -> Int in ... } // full form
 
 or as:
 
 let closure: () -> Int = { [weak self, bar] in ... } // full form
 
 which allows this change:
 
 let closure:  [weak self, bar] () -> Int = { ... } // full alt form
 
 or in alternative form:
 
 let closure:  weak () -> Int = { [bar] in ... } // short hand form
 
 same can be with functions:
 
 func fn() -> Int { [weak self, bar] in ... } // full form
 
 weak func fn() -> Int { [bar] in ... } // short hand form
 
 the two capture attributes will in practice be "close" to each other:
 
 weak func fn() {
 [bar] in
 
 }
 
 and in majority of cases there will be only weak self:
 
 weak func fn() {
 
 }
 
 Mike
 
 
 ___
 swift-evolution mailing list
 swift-evolution@swift.org
 https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>>> 
>>> 

Re: [swift-evolution] [Pitch] Improving capturing semantics of local functions

2017-11-14 Thread Robert Widmann via swift-evolution
A quick thing I noticed on a first read (sort of tangential to the rest of the 
discussion) is that it would be a good idea to land warnings for potential 
reference cycles sooner rather than later.

I have an (un-rebased) branch that lays out what parts of Sema needs to be 
touched to make this happen and have SR-1807 
(https://bugs.swift.org/browse/SR-1807) open for this in general if anybody 
would like to pick this up and carry it over the goal line.  Note that it’s not 
quite a starter bug.

Otherwise I’ll allocate time to it later on this winter.

~Robert Widmann 

2017/11/15 2:01、David Hart via swift-evolution のメール:

> 
> 
>> On 15 Nov 2017, at 03:56, Howard Lovatt via swift-evolution 
>>  wrote:
>> 
>> Having read all the arguments for what to add to local functions it still 
>> strikes me as a poor use of engineering resources to fix them (though I do 
>> agree they have problems). A better use of resources would be:
>> 
>>   1. Deprecate local functions.
> 
> Even if I agreed, which I don’t, I’m fairly sure it’s much too late in 
> Swift’s timeline to deprecate something as huge as local functions.
> 
>>   2. Allow closures when assigned to a function type to be:
>>   2a. Recursive.
>>   2b. Annotatable with:
>> 2bi.  @inline
>> 2bii. @escaping
>>   2c. Generic.
>> 
>> That would be a similar engineering effort and give a better short term 
>> result of better closures which would be much more widely applicable as well 
>> as addressing the issues with local functions.
>> 
>> It also gives a better long term result of not having to maintain local 
>> functions.
>>   
>> 
>>   -- Howard.
>> 
>>> On 15 November 2017 at 09:08, Alex Lynch via swift-evolution 
>>>  wrote:
>>> The inference algebra just suggested was enjoyable to read, but is still a 
>>> new syntax. Which is interesting and deserving of its own proposal. The 
>>> purpose of this proposal is simply to introduce the existing capture syntax 
>>> to local functions. Thanks to everyone's feedback pointing out that the 
>>> `self` reference analysis is a deeper question than initially realized. 
>>> 
>>> Alex
>>> 
 On Tue, Nov 14, 2017 at 4:36 PM, Mike Kluev via swift-evolution 
  wrote:
> On 14 November 2017 at 21:02, David Hart  wrote:
 
> 
> 
> I’d be very hesitant to introduce this syntax:
> 
> it’s new syntax, so it comes with a complexity tax (it isn’t naturally 
> obvious what it means for a func to be weak)
> it’s only sugar for the capture of self
 
 it might cover well over 90% of use cases (by my "pessimistic" 
 estimate)... if someone has a quick way to scan and analyse, say, github 
 swift sources we may even know that current percentage number of real life 
 usage.
> it doesn’t transpose well to local closures
 
 the last one - maybe not. follow me:
 
 let closure = { [weak self, bar] in ... }
 
 which today can be written as: 
 
 let closure = { [weak self, bar] () -> Int in ... } // full form
 
 or as:
 
 let closure: () -> Int = { [weak self, bar] in ... } // full form
 
 which allows this change:
 
 let closure:  [weak self, bar] () -> Int = { ... } // full alt form
 
 or in alternative form:
 
 let closure:  weak () -> Int = { [bar] in ... } // short hand form
 
 same can be with functions:
 
 func fn() -> Int { [weak self, bar] in ... } // full form
 
 weak func fn() -> Int { [bar] in ... } // short hand form
 
 the two capture attributes will in practice be "close" to each other:
 
 weak func fn() {
 [bar] in
 
 }
 
 and in majority of cases there will be only weak self:
 
 weak func fn() {
 
 }
 
 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 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] [swift-dev] Re-pitch: Deriving collections of enum cases

2017-11-10 Thread Robert Widmann via swift-evolution

> On Nov 6, 2017, at 2:54 AM, Jacob Bandes-Storch via swift-dev 
>  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.

Generalizing the result type is probably a good thing to do before we finalize 
the user-facing component of this.  I wrote the interface with an Array at the 
time because it was easy and because the first implementation of this tried to 
directly synthesize an array literal expression.

> 
> 
> **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."
> 
> My understanding of the runtime/importer is very shallow, but with the 
> current metadata-based strategy, I suspect imported enums couldn't be 
> supported at all, or if they could, the metadata would be generated at import 
> time rather than loaded dynamically from the library, which naturally 
> wouldn't behave the same way when you drop in an upgraded version of the 
> library. Is that correct?

Exactly.  Today, we don’t write out metadata for foreign enumerations and it 
would be interesting to see how that would look if we decide to do so in the 
future.  Either way, leaving it up to the authors of Objective-C/C to create a 
Swift wrapper to get access to this protocol is a little unfortunate, but not 
that big a deal ultimately.

> 
> - Enums with availability annotations on some cases. Doug Gregor writes: "if 
> I have a case that’s only available on macOS 10.12 and newer, it probably 
> shouldn’t show up if I use allValues when running on macOS 10.11."
> 
> If we fetch cases from the enum metadata, does this "just work" since the 
> metadata will 

Re: [swift-evolution] [SE-0155][Discuss] The role of labels in enum case patterns

2017-09-08 Thread Robert Widmann via swift-evolution
t;>>>> On Sun, Sep 3, 2017 at 4:35 PM, Xiaodi Wu via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> The desired behavior was the major topic of controversy during review; 
>>>>> I’m wary of revisiting this topic as we are essentially relitigating the 
>>>>> proposal.
>>>>> 
>>>>> To start off, the premise, if I recall, going into review was that the 
>>>>> author **rejected** the notion that pattern matching should mirror 
>>>>> creation. I happen to agree with you on this point, but it was not the 
>>>>> prevailing argument. Fortunately, we do not need to settle this to arrive 
>>>>> at some clarity for the issues at hand.
>>>>> 
>>>>> From a practical standpoint, a requirement for labels in all cases would 
>>>>> be much more source-breaking, whereas the proposal as it stands would 
>>>>> allow currently omitted labels to continue being valid. Moreover, and I 
>>>>> think this is a worthy consideration, one argument for permitting the 
>>>>> omission of labels during pattern matching is to encourage API designers 
>>>>> to use labels to clarify initialization without forcing its use by API 
>>>>> consumers during every pattern matching operation.
>>>>> 
>>>>> In any case, the conclusion reached is precedented in the world of 
>>>>> functions:
>>>>> 
>>>>> func g(a: Int, b: Int) { ... }
>>>>> let f = g
>>>>> f(1, 2)
>>>>> 
>>>>> On Sun, Sep 3, 2017 at 15:13 Robert Widmann via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> Hello Swift Evolution,
>>>>> 
>>>>> I took up the cause of implementing SE-0155 
>>>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md>,
>>>>>  and am most of the way through the larger points of the proposal.  One 
>>>>> thing struck me when I got to the part about normalizing the behavior of 
>>>>> pattern matching 
>>>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md#pattern-consistency>.
>>>>>   The Core Team indicated in their rationale 
>>>>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170417/035972.html>
>>>>>  that the proposal’s suggestion that a variable binding sub in for a 
>>>>> label was a little much as in this example:
>>>>> 
>>>>> enum Foo {
>>>>>   case foo(x: Int, y: Int)
>>>>> }
>>>>> if case let .foo(x: x, y: y) {} // Fine!  Labels match and are in order
>>>>> if case let .foo(x, y: y) {} // Bad!  Missing label 'x'
>>>>> if case let .foo(x, y) {} // Fine?  Missing labels, but variable names 
>>>>> match labels
>>>>> 
>>>>> They instead suggested the following behavior:
>>>>> 
>>>>> enum Foo {
>>>>>   case foo(x: Int, y: Int)
>>>>> }
>>>>> if case let .foo(x: x, y: y) {} // Fine!  Labels match and are in order
>>>>> if case let .foo(x, y: y) {} // Bad!  Missing label 'x'
>>>>> if case let .foo(x, y) {} // Fine?  Missing labels, and full name of case 
>>>>> is unambiguous
>>>>> 
>>>>> Which, for example, would reject this:
>>>>> 
>>>>> enum Foo {
>>>>>   case foo(x: Int, y: Int) // Note: foo(x:y:)
>>>>>   case foo(x: Int, z: Int) // Note: foo(x:z:)
>>>>> }
>>>>> if case let .foo(x, y) {} // Bad!  Are we matching foo(x:y:) or foo(x:z:)?
>>>>> 
>>>>> With this reasoning:
>>>>> 
>>>>>>  - While an associated-value label can indeed contribute to the 
>>>>>> readability of the pattern, the programmer can also choose a meaningful 
>>>>>> name to bind to the associated value.  This binding name can convey at 
>>>>>> least as much information as a label would.
>>>>>> 
>>>>>>   - The risk of mis-labelling an associated value grows as the number of 
>>>>>> associated values grows.  However, very few cases carry a large number 
>>>>>> of a

Re: [swift-evolution] [SE-0155][Discuss] The role of labels in enum case patterns

2017-09-08 Thread Robert Widmann via swift-evolution
berwise initializer.  It 
>> might not even be possible to reconstruct initializer arguments for the sake 
>> of parallel destructuring syntax.  There might even be more than one 
>> projection that is reasonable to use when destructuring the value in a 
>> pattern (such as cartesian and polar coordinates).
>> 
>> FWIW, I made this case in more detail during the discussion and review of 
>> this proposal.
>> 
>>> 
>>> On Sun, Sep 3, 2017 at 4:35 PM, Xiaodi Wu via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> The desired behavior was the major topic of controversy during review; I’m 
>>> wary of revisiting this topic as we are essentially relitigating the 
>>> proposal.
>>> 
>>> To start off, the premise, if I recall, going into review was that the 
>>> author **rejected** the notion that pattern matching should mirror 
>>> creation. I happen to agree with you on this point, but it was not the 
>>> prevailing argument. Fortunately, we do not need to settle this to arrive 
>>> at some clarity for the issues at hand.
>>> 
>>> From a practical standpoint, a requirement for labels in all cases would be 
>>> much more source-breaking, whereas the proposal as it stands would allow 
>>> currently omitted labels to continue being valid. Moreover, and I think 
>>> this is a worthy consideration, one argument for permitting the omission of 
>>> labels during pattern matching is to encourage API designers to use labels 
>>> to clarify initialization without forcing its use by API consumers during 
>>> every pattern matching operation.
>>> 
>>> In any case, the conclusion reached is precedented in the world of 
>>> functions:
>>> 
>>> func g(a: Int, b: Int) { ... }
>>> let f = g
>>> f(1, 2)
>>> 
>>> On Sun, Sep 3, 2017 at 15:13 Robert Widmann via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> Hello Swift Evolution,
>>> 
>>> I took up the cause of implementing SE-0155 
>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md>,
>>>  and am most of the way through the larger points of the proposal.  One 
>>> thing struck me when I got to the part about normalizing the behavior of 
>>> pattern matching 
>>> <https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md#pattern-consistency>.
>>>   The Core Team indicated in their rationale 
>>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170417/035972.html>
>>>  that the proposal’s suggestion that a variable binding sub in for a label 
>>> was a little much as in this example:
>>> 
>>> enum Foo {
>>>   case foo(x: Int, y: Int)
>>> }
>>> if case let .foo(x: x, y: y) {} // Fine!  Labels match and are in order
>>> if case let .foo(x, y: y) {} // Bad!  Missing label 'x'
>>> if case let .foo(x, y) {} // Fine?  Missing labels, but variable names 
>>> match labels
>>> 
>>> They instead suggested the following behavior:
>>> 
>>> enum Foo {
>>>   case foo(x: Int, y: Int)
>>> }
>>> if case let .foo(x: x, y: y) {} // Fine!  Labels match and are in order
>>> if case let .foo(x, y: y) {} // Bad!  Missing label 'x'
>>> if case let .foo(x, y) {} // Fine?  Missing labels, and full name of case 
>>> is unambiguous
>>> 
>>> Which, for example, would reject this:
>>> 
>>> enum Foo {
>>>   case foo(x: Int, y: Int) // Note: foo(x:y:)
>>>   case foo(x: Int, z: Int) // Note: foo(x:z:)
>>> }
>>> if case let .foo(x, y) {} // Bad!  Are we matching foo(x:y:) or foo(x:z:)?
>>> 
>>> With this reasoning:
>>> 
>>>>  - While an associated-value label can indeed contribute to the 
>>>> readability of the pattern, the programmer can also choose a meaningful 
>>>> name to bind to the associated value.  This binding name can convey at 
>>>> least as much information as a label would.
>>>> 
>>>>   - The risk of mis-labelling an associated value grows as the number of 
>>>> associated values grows.  However, very few cases carry a large number of 
>>>> associated values.  As the amount of information which the case should 
>>>> carry grows, it becomes more and more interest

Re: [swift-evolution] [SE-0155][Discuss] The role of labels in enum case patterns

2017-09-08 Thread Robert Widmann via swift-evolution
@swift.org>> wrote:
>> 
>> While re-litigating has it's issues, I am for simplifying the rule and 
>> always requiring the labels if they exist. This is similar to the change 
>> around external labels. Yes, it is slightly less convenient, but it removes 
>> a difficult to motivate caveat for beginners.
>> 
>> On Sun, Sep 3, 2017 at 4:35 PM, Xiaodi Wu via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> The desired behavior was the major topic of controversy during review; I’m 
>> wary of revisiting this topic as we are essentially relitigating the 
>> proposal.
>> 
>> To start off, the premise, if I recall, going into review was that the 
>> author **rejected** the notion that pattern matching should mirror creation. 
>> I happen to agree with you on this point, but it was not the prevailing 
>> argument. Fortunately, we do not need to settle this to arrive at some 
>> clarity for the issues at hand.
>> 
>> From a practical standpoint, a requirement for labels in all cases would be 
>> much more source-breaking, whereas the proposal as it stands would allow 
>> currently omitted labels to continue being valid. Moreover, and I think this 
>> is a worthy consideration, one argument for permitting the omission of 
>> labels during pattern matching is to encourage API designers to use labels 
>> to clarify initialization without forcing its use by API consumers during 
>> every pattern matching operation.
>> 
>> In any case, the conclusion reached is precedented in the world of functions:
>> 
>> func g(a: Int, b: Int) { ... }
>> let f = g
>> f(1, 2)
>> 
>> On Sun, Sep 3, 2017 at 15:13 Robert Widmann via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> Hello Swift Evolution,
>> 
>> I took up the cause of implementing SE-0155 
>> <https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md>,
>>  and am most of the way through the larger points of the proposal.  One 
>> thing struck me when I got to the part about normalizing the behavior of 
>> pattern matching 
>> <https://github.com/apple/swift-evolution/blob/master/proposals/0155-normalize-enum-case-representation.md#pattern-consistency>.
>>   The Core Team indicated in their rationale 
>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170417/035972.html>
>>  that the proposal’s suggestion that a variable binding sub in for a label 
>> was a little much as in this example:
>> 
>> enum Foo {
>>   case foo(x: Int, y: Int)
>> }
>> if case let .foo(x: x, y: y) {} // Fine!  Labels match and are in order
>> if case let .foo(x, y: y) {} // Bad!  Missing label 'x'
>> if case let .foo(x, y) {} // Fine?  Missing labels, but variable names match 
>> labels
>> 
>> They instead suggested the following behavior:
>> 
>> enum Foo {
>>   case foo(x: Int, y: Int)
>> }
>> if case let .foo(x: x, y: y) {} // Fine!  Labels match and are in order
>> if case let .foo(x, y: y) {} // Bad!  Missing label 'x'
>> if case let .foo(x, y) {} // Fine?  Missing labels, and full name of case is 
>> unambiguous
>> 
>> Which, for example, would reject this:
>> 
>> enum Foo {
>>   case foo(x: Int, y: Int) // Note: foo(x:y:)
>>   case foo(x: Int, z: Int) // Note: foo(x:z:)
>> }
>> if case let .foo(x, y) {} // Bad!  Are we matching foo(x:y:) or foo(x:z:)?
>> 
>> With this reasoning:
>> 
>>>  - While an associated-value label can indeed contribute to the readability 
>>> of the pattern, the programmer can also choose a meaningful name to bind to 
>>> the associated value.  This binding name can convey at least as much 
>>> information as a label would.
>>> 
>>>   - The risk of mis-labelling an associated value grows as the number of 
>>> associated values grows.  However, very few cases carry a large number of 
>>> associated values.  As the amount of information which the case should 
>>> carry grows, it becomes more and more interesting to encapsulate that 
>>> information in its own struct — among other reasons, to avoid the need to 
>>> revise every matching case-pattern in the program.  Furthermore, when a 
>>> case does carry a significant number of associated values, there is often a 
>>> positional conventional between them that lowers the risk of re-ordering: 
>>> for example, the conventional left-then-right ordering of a binary search 
&g

[swift-evolution] [SE-0155][Discuss] The role of labels in enum case patterns

2017-09-03 Thread Robert Widmann via swift-evolution
Hello Swift Evolution,

I took up the cause of implementing SE-0155 
,
 and am most of the way through the larger points of the proposal.  One thing 
struck me when I got to the part about normalizing the behavior of pattern 
matching 
.
  The Core Team indicated in their rationale 

 that the proposal’s suggestion that a variable binding sub in for a label was 
a little much as in this example:

enum Foo {
  case foo(x: Int, y: Int)
}
if case let .foo(x: x, y: y) {} // Fine!  Labels match and are in order
if case let .foo(x, y: y) {} // Bad!  Missing label 'x'
if case let .foo(x, y) {} // Fine?  Missing labels, but variable names match 
labels

They instead suggested the following behavior:

enum Foo {
  case foo(x: Int, y: Int)
}
if case let .foo(x: x, y: y) {} // Fine!  Labels match and are in order
if case let .foo(x, y: y) {} // Bad!  Missing label 'x'
if case let .foo(x, y) {} // Fine?  Missing labels, and full name of case is 
unambiguous

Which, for example, would reject this:

enum Foo {
  case foo(x: Int, y: Int) // Note: foo(x:y:)
  case foo(x: Int, z: Int) // Note: foo(x:z:)
}
if case let .foo(x, y) {} // Bad!  Are we matching foo(x:y:) or foo(x:z:)?

With this reasoning:

>  - While an associated-value label can indeed contribute to the readability 
> of the pattern, the programmer can also choose a meaningful name to bind to 
> the associated value.  This binding name can convey at least as much 
> information as a label would.
> 
>   - The risk of mis-labelling an associated value grows as the number of 
> associated values grows.  However, very few cases carry a large number of 
> associated values.  As the amount of information which the case should carry 
> grows, it becomes more and more interesting to encapsulate that information 
> in its own struct — among other reasons, to avoid the need to revise every 
> matching case-pattern in the program.  Furthermore, when a case does carry a 
> significant number of associated values, there is often a positional 
> conventional between them that lowers the risk of re-ordering: for example, 
> the conventional left-then-right ordering of a binary search tree.  Therefore 
> this risk is somewhat over-stated, and of course the programmer should remain 
> free to include labels for cases where they feel the risk is significant.
> 
>   - It is likely that cases will continue to be predominantly distinguished 
> by their base name alone.  Methods are often distinguished by argument labels 
> because the base name identifies an entire class of operation with many 
> possible variants.  In contrast, each case of an enum is a kind of data, and 
> its name is conventionally more like the name of a property than the name of 
> a method, and thus likely to be unique among all the cases.  Even when cases 
> are distinguished using only associated value labels, it simply means that 
> the corresponding case-patterns must include those labels; we should not feel 
> required to force that burden on all other case-patterns purely to achieve 
> consistency with this presumably-unusual style.
> Accordingly, while it needs to be possible to include associated value labels 
> in a case-pattern, and in some situations it may be wise to include them, the 
> core team believes that requiring associated value labels would be unduly 
> onerous.


This sounds fine in principle, but I believe it is inconsistent with the goals 
of the proposal and doesn’t actually normalize much about the existing pattern 
matching process.  As it stands, labels may be omitted from patterns because 
Swift’s philosophy before this proposal is that associated values in enum cases 
were conceptually tuples.  With the addition of default arguments, the ability 
to overload case names with differing associated value labels, and making the 
labels part of the API name, there is no reason we should allow tuple-like 
behavior in just this one case.

> While an associated-value label...

While it is true that a user often has a domain-specific intention for 
variables created during the destructuring process, the labels do not distract 
from the original purpose of the API and the user is still free to provide 
whatever name they see fit.

> Therefore this risk is somewhat over-stated, and of course the programmer 
> should remain free to include labels for cases where they feel the risk is 
> significant...

This is phrased as a matter of choice, in practice this is perplexing.  Recall 
an earlier rejected pattern:

enum Foo {
  case foo(x: Int, y: Int)
}
if case let .foo(x, y: y) {} // Bad!  Missing label ‘x'

>From the user’s perspective, it is obvious what should happen: Either 

Re: [swift-evolution] [discussion] Class stored properties?

2017-08-09 Thread Robert Widmann via swift-evolution
This is a singleton, it just happens to be in class scope.

~Robert Widmann

> On Aug 9, 2017, at 3:55 AM, Mathew Huusko V via swift-evolution 
>  wrote:
> 
> Curious if class stored properties have ever been discussed (doesn't seem 
> so..)?
> 
> Also, assuming no, and assuming there's a good reason no/they're not coming 
> anytime soon, what are some patterns people have been using in their place? I 
> was considering something like..
> 
> class SomeClass {
> private static var _classValues = [SomeClass.Type: Int]()
> 
> class var value: Int {
> get { _classValues[self] }
> set { _classValues[self] = newValue }
> }
> }
> 
> .. but then I remembered types aren't hashable yet either (so I guess I need 
> to stringify it first).
> ___
> 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] [Idea] Creating an enums as a sum of multiple other enums

2017-07-31 Thread Robert Widmann via swift-evolution
Not a response to the core of this, but to the motivating example: Sectioned 
(or multi-sorted in other cases) ASTs can also be represented by a 
singly-sorted AST and views over top

enum UnaryOperatorView {
  case not
}

enum BinaryOperatorView {
  case and
  case or
}

enum BooleanLiteralView {
  case `true`
  case `false`
}

enum Token {
  case not
  case and, or
  case `true`, `false`
  
  var asUnaryOperator: UnaryOperatorView? {
switch self {
case .not: return .not
default: return nil
}
  }
  
  /*etc.*/
}

The Valence library uses this to great effect 
.

~Robert Widmann

> On Jul 31, 2017, at 5:43 PM, Ahmad Alhashemi via swift-evolution 
>  wrote:
> 
> I’ve been writing an interpreter in Swift and have been finding enums 
> incredibly useful. One feature thought that I thought would make life easier 
> is the ability to create a super-enum that contains as its cases all the 
> cases of its constituent enums:
> 
>> enum UnaryOperator {
>>case not
>> }
>> 
>> enum BinaryOperator {
>>case and
>>case or
>> }
>> 
>> case BooleanLiteral {
>>case `true`
>>case `false`
>> }
>> 
>> typealias Token = UnaryOperator | BinaryOperator | BooleanLiteral
> 
> It would then be possible to do something like this:
> 
>> scanToken() -> Token
>> 
>> indirect enum Expr {
>>case binary(op: BinaryOperator, lhs: Expr, rhs: Expr)
>> }
> 
> For example, a number of functions in the recursive descent parser can only 
> return a subset of all possible expressions.
> 
> Of course it’s already possible to represent the same data structure like 
> this:
> 
>> enum Token {
>>case binaryOperator(BinaryOperator)
>>case unaryOperator(UnaryOperator)
>>case booleanLiteral(BooleanLiteral)
>> }
> 
> Perhaps what I’m suggesting could just be syntactic sugar, but it’d make it 
> much easier to switch over `Token` without worrying about all of the nested 
> enums. The feature becomes even more useful if you think about a deeper 
> hierarchy of enums. It would bring some of the power of protocols/POP to 
> enums.
> 
> This raises a few questions such as:
> - Case name collisions
> - Associated types
> - Raw values
> 
> But I can’t think of anything that cannot be addressed with sensible rules 
> and conditions.
> 
> Interested to read your thoughts.
> 
> -Ahmad
> ___
> 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] Update to Alternative Types (i.e. strong typedef) Proposal

2017-07-31 Thread Robert Widmann via swift-evolution


> On Jul 31, 2017, at 4:08 PM, Daryle Walker  wrote:
> 
>> On Jul 31, 2017, at 1:45 PM, Robert Widmann > > wrote:
>> 
>> As I was saying, I agree with the overall usefulness of newtype-style 
>> declarations, but I don’t understand why we need so much syntax for what 
>> should just be a pattern in Swift.  Specifically, the idea of automatic 
>> delegation of an interface is antithetical to the very reason why Haskell 
>> has newtype in the first place.  And in the situations in which I would 
>> create an alternate definition of a type, I expect to never inherit the 
>> interface of the underlying type because I intend for it to be completely 
>> distinct. 
> 
> What would this pattern look like?

Today, a struct wrapping a single stored property will give you both the static 
and dynamic semantics you’re looking for.  All that’s left is the delegation.

> 
> An alternative inherits nothing by default. You have to explicitly publish 
> members from the underlying type to the current one. And you don’t have to; 
> you can leave members out, or implement trampolines yourself. I wanted 
> something between Go’s taking everything and C++’s taking nothing, more 
> selectable like Haskell. (But I don’t really understand Haskell.)

Haskell’s newtype feature does not provide this kind of delegation.  It’s in 
the “taking nothing” camp.

> 
>> Additionally, the use of inheritance in alternate definitions seems out of 
>> place and the casting section breaks encapsulation.
> 
> Enumerations use similar syntax to specify their raw type. What word, which 
> may have to be new, should be used to serve a similar function as “super” 
> within the main initializer?

Treating an alternate like a protocol is fine - there is prior art in protocols 
for that.  But having alternatives refine each other doesn’t make much sense to 
me without a more salient example than the one in the proposal.  

> 
> Isn’t breaking (or at least bending) encapsulation a point of casting? And 
> shorter than calling “rawValue” and/or “init?” a bunch of times?

A cast in C and C++ may be so, but we encourage checked casts where possible 
and allow you access to the old “a promise to the compiler” kind of casting 
with unsafeBitCast - and even then we check sizes.  We should try to avoid 
leaking implementation details like this.

~Robert Widmann

> 
> — 
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com 
> 

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


Re: [swift-evolution] [Pitch][Bug?] Test for Anti-Conformance During Generics

2017-07-31 Thread Robert Widmann via swift-evolution


> On Jul 31, 2017, at 10:34 AM, Daryle Walker via swift-evolution 
>  wrote:
> 
> 
>> On Jul 31, 2017, at 1:33 AM, Daryle Walker > > wrote:
>> 
>>> On Jul 31, 2017, at 1:19 AM, Xiaodi Wu >> > wrote:
>>> 
>>> Daryle, this discussion has indeed taken place before. One good place to 
>>> start is the Google result for "swift evolution non-conformance".
>> 
>> I added SR-5589, to request a counter protocol to AnyObject.
> 
> Part of the response that closed this as “Won’t Do” was:
> 
>> AnyObject is no longer a protocol
> 
> 
> Then, what is it?

Relevant https://github.com/apple/swift/pull/8749 
 

> 
> — 
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com 
> 
> ___
> 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] Update to Alternative Types (i.e. strong typedef) Proposal

2017-07-31 Thread Robert Widmann via swift-evolution
(Excuse me, my last reply was sent prematurely)

As I was saying, I agree with the overall usefulness of newtype-style 
declarations, but I don’t understand why we need so much syntax for what should 
just be a pattern in Swift.  Specifically, the idea of automatic delegation of 
an interface is antithetical to the very reason why Haskell has newtype in the 
first place.  And in the situations in which I would create an alternate 
definition of a type, I expect to never inherit the interface of the underlying 
type because I intend for it to be completely distinct. 

Additionally, the use of inheritance in alternate definitions seems out of 
place and the casting section breaks encapsulation.

~Robert Widmann


> On Jul 29, 2017, at 4:01 PM, Daryle Walker via swift-evolution 
>  wrote:
> 
> Proposal at 
>  >, 
> uploaded revision 4.
> 
> Changes:
> 
> Since the original setup was a poor copy of how raw-style enumerations use 
> RawRepresentable, changed the model to actually use RawRepresentable. 
> Actually, it uses a sub-protocol, AnyAlternative, which adds an associated 
> type for the implementing non-alternative type. AnyAlternative also serves a 
> function like AnyObject.
> Removed the old library support type since it’s obsolete. Added back a (now 
> global) function to upcast to the implementation type without needing to name 
> it.
> Added option to initialize alternative by assigning to “super.” Using “super” 
> by itself isn’t allowed in the grammar (It has to be followed by a member 
> specification), so I added it.
> Added note about pointer compatibility.
> The model change led to a lot of rewording. And new/changed technical terms.
> 
> — 
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com 
> 
> ___
> 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] Update to Alternative Types (i.e. strong typedef) Proposal

2017-07-31 Thread Robert Widmann via swift-evolution
I agree with the overall usefulness of newtype-style (

> On Jul 29, 2017, at 4:01 PM, Daryle Walker via swift-evolution 
>  wrote:
> 
> Proposal at 
>  >, 
> uploaded revision 4.
> 
> Changes:
> 
> Since the original setup was a poor copy of how raw-style enumerations use 
> RawRepresentable, changed the model to actually use RawRepresentable. 
> Actually, it uses a sub-protocol, AnyAlternative, which adds an associated 
> type for the implementing non-alternative type. AnyAlternative also serves a 
> function like AnyObject.
> Removed the old library support type since it’s obsolete. Added back a (now 
> global) function to upcast to the implementation type without needing to name 
> it.
> Added option to initialize alternative by assigning to “super.” Using “super” 
> by itself isn’t allowed in the grammar (It has to be followed by a member 
> specification), so I added it.
> Added note about pointer compatibility.
> The model change led to a lot of rewording. And new/changed technical terms.
> 
> — 
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com 
> 
> ___
> 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] Recent change makes Swift 4 less safe.

2017-07-31 Thread Robert Widmann via swift-evolution
I don’t agree with your assertions that this makes Swift “less safe” - if 
anything the bug that this fixed was anything but.  When performing a pattern 
match, we expect the pattern to match the “shape” of the declaration itself.  
If ‘()’ was not part of that declaration, then you have no reason to indicate 
this as part of a pattern.  Consider a slightly more extreme case that was 
allowed before we fixed this bug (and, for compatibility reasons, is still 
allowed in Swift 3 mode)

enum E {
  case A, B, C, D
}

func testE(e: E) {
  switch e {
  case .A(let x): print(x)
  default: break
  }
}

Assuming this survives SILGen, which it often doesn’t, what do you feel a 
reasonable value for “x” should be?  Our compiler thinks (thought?) ‘Void’.

~Robert Widmann

> On Jul 28, 2017, at 2:23 PM, Amir Michail via swift-evolution 
>  wrote:
> 
> The latest beta doesn’t allow you to append “()” to an enum name with no 
> associated value in a switch case.
> 
> This makes Swift less safe because appending that “()” is an excellent way to 
> indicate that you are not ignoring the associated value in the swift case 
> because there isn’t any.
> 
> Suppose that you later add an associated value. Then the switch case with the 
> “()” will give a compile error, which is better than silently introducing a 
> bug into your code.
> 
> ___
> 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] Array full proposal

2017-07-13 Thread Robert Widmann via swift-evolution


> On Jul 12, 2017, at 9:09 PM, Daryle Walker  wrote:
> 
> 
>> On Jul 12, 2017, at 4:05 PM, Robert Widmann  wrote:
>> 
>> I think this proposal is trying to do too much at once.  Correct me if I’m 
>> wrong, but you’re proposing
>> 
>> 1) New sugar for fixed-length arrays without a corresponding stdlib 
>> declaration
> 
> IIUC, “sugar” means an easier way to use existing functionality, right? In 
> this proposal, there is neither sugar nor a standard library declaration for 
> the same reason: these arrays are a new primitive at the user and ABI levels, 
> not a library type. What is the (existing since you mentioned sugar) 
> primitive you’re expecting a library fixed-size array to be based on?

“Sugar” means an equivalent way to spell something concrete, but here there is 
nothing concrete.  We’d be hard-coding a magical library type into the compiler 
which is something that, up to now, we have refrained from doing because it 
massively complicates type checking and forces us to compromise to work around 
“just this one corner case”.   Our notion of a “primitive” is not the same as C 
and C++; Int, Float, String, these are all Standard Library types - that happen 
to be backed by compiler intrinsics in some cases.

> 
> Obviously, this means arrays can’t be implemented until at least Swift 5.
> 
>> 2) Arity and type inference for literals
> 
> I don’t know what you mean by these.


var b: [_, _] = [3.14159, 2.71828]

On the syntactic side: underbar has a very specific meaning in this language, 
and “infer this type/arity” isn’t one of them.

> 
>> 3) Default initialization semantics for arrays including a DI exception for 
>> fixed-length arrays that aren’t fully initialized 
> 
> My first thought was full initialization, like other objects, but someone on 
> the list really wanted a way to not have full initialization. I could see his 
> point; filling in a bunch of zeros for a large array for math purposes could 
> get expensive, especially if the values are immediately ran over. Even if we 
> make closure-initialization return non-optionals, we still have to worry when 
> an array is filled by a loop that gets exited early.

As long as you have this magical type, you should probably give it some magical 
methods.  A “backfill” initializer, perhaps.  We cannot break DI just because 
it’s syntactically inconvenient.

You’ve also stumbled onto the notion of a “reasonable default”, which for a 
language with a rich type system is a farce.  We can’t assume every type has 
some reasonable default that we can fill in automatically because many types 
don’t (for an extreme example, see Never).

> 
>> 4) 2 new attribute declarations for unspecified concurrency semantics
> 
> Why not add some modern features relative to classic C? Or is it possible for 
> these to be automatically determined (and carried out) by the compiler? I 
> don’t think the vector-unit one can.

You must define these semantics.  We cannot hand-wave about something so 
massively complicated.  For one, I don’t know what “automatically determined” 
in regards to a non-referentially-transparent language means.

> 
>> 5) A magical compiler intrinsic that declares loop counters
> 
> Having the compiler figure out the best way to iterate an array seems a lot 
> better than manually doing a bunch of loop and range calls, especially for 
> multi-dimensional arrays. (I want one loop statement, no matter the number of 
> dimensions.) But without those manual calls, you need some other way to 
> determine your position in the loop.
> 

See above.  Auto-vectorization semantics are great, but we have to have them 
defined first.

>> 6) Static collection subtyping constraints referencing convertibility 
>> constraints we don’t currently have
> 
> I copied that from the section of the ABI document about tuples. We could 
> drop it.
> 
>> 7) Tuple conversions
> 
> Since these arrays will replace manually homogenous tuples as the conversion 
> for C arrays, we need a way to handle older code. I probably wouldn’t have 
> bothered except for backwards compatibility.

We control the import of those “tuples", so we could switch them to be imported 
as your new type.  If you can make your proposal function in a 
backwards-compatible manner we wouldn’t need this.

> 
> Are manually homogenous tuples, with the multiplicity of the element type is 
> specified with lexical repetition instead of a number, the sugar from point 
> 1? If so, that use would be depreciated, not continued.
> 
>> I believe your aims are noble, and this is certainly a tremendously 
>> important problem we need to solve, but I think there needs to be a measured 
>> response to the current state of things.
> 
> — 
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com 
> 

___
swift-evolution mailing list
swift-evolution@swift.org

Re: [swift-evolution] Better handling of enum cases with associated values

2017-07-12 Thread Robert Widmann via swift-evolution
I like the spirit of this idea because it matches features found in other 
languages that have prominent pattern matching (ML, Haskell, etc.).  But I’m 
concerned about the overloading of existing syntax for this case.  Plus, if you 
find yourself destructuring large enum cases like this, have you considered 
making a struct containing those fields?

enum Value {
  struct Leaf {
let data: Any?, moreData: Any?, evenMoreData: Any?
  }
  case container(leafs: [Value])
  case leaf(Leaf)
}

func foo(_ v : Value) {
  switch v {
  case let .leaf(x):
print(x.data, x.moreData, x.evenMoreData)
  case .container:
break
  }
}

~Robert Widmann

> On Jul 10, 2017, at 8:35 AM, Sash Zats via swift-evolution 
>  wrote:
> 
> Hi, I wanted to propose a better handling of enum cases with associated value
> (somewhat) detailed proposal is here 
> https://github.com/zats/swift-evolution/blob/master/proposals/0181-better-handling-of-enum-cases-with-associated-values.md
>  
> 
> I'm not sure I can suggest good detailed implementation since I'm not too 
> familiar with Swift internals
> But i'm sure it's something I can research if proposal makes sense to 
> community
> Since I havne't communicated through this mailing list, I'm not sure what's 
> the etiquette, let me know if something is missing from the proposal.
> ___
> 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] Array full proposal

2017-07-12 Thread Robert Widmann via swift-evolution
I think this proposal is trying to do too much at once.  Correct me if I’m 
wrong, but you’re proposing

1) New sugar for fixed-length arrays without a corresponding stdlib declaration
2) Arity and type inference for literals
3) Default initialization semantics for arrays including a DI exception for 
fixed-length arrays that aren’t fully initialized 
4) 2 new attribute declarations for unspecified concurrency semantics
5) A magical compiler intrinsic that declares loop counters
6) Static collection subtyping constraints referencing convertibility 
constraints we don’t currently have
7) Tuple conversions

I believe your aims are noble, and this is certainly a tremendously important 
problem we need to solve, but I think there needs to be a measured response to 
the current state of things.

~Robert Widmann

> On Jul 10, 2017, at 9:54 PM, Daryle Walker via swift-evolution 
>  wrote:
> 
> Spent the past week coming up with a full proposal for fixed-size arrays. I 
> wrote it mainly from the bottom upwards. There may be some inconsistencies. 
> And I'm not entirely sure what "structural sub-typing" means, or if it's 
> appropriate for arrays.
> 
>  >
> 
> Sent from my iPad
> ___
> 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] SE-0168: Multi-Line String Literals

2017-05-26 Thread Robert Widmann via swift-evolution
A quick question since we’ve already accepted this proposal and have an 
implementation in-tree: do you expect this breaking change to be accepted for 
Swift 4, or do you expect this change to break everybody once they’ve already 
migrated to the triple-quoted string form in a future release?

~Robert Widmann

> On May 25, 2017, at 11:02 PM, Dave Yost via swift-evolution 
>  wrote:
> 
> 
> Beauty is a top-three goal of Swift, so a proposal that is not beautiful 
> should be rethought until it is.
> 
> 1. """ is ugly.
> 
> 2. Choosing syntax so as to pander to hacks in a few existing tools is the 
> road to Ugly.
> 
> 3. It’s inelegant syntax design for start and end delimiters to be identical, 
> as for example ASCII quote marks are.[1]
> 
> 4. Mirror image start and end delimiters are preferred, for example { and 
> }.[1]
> 
> 5. Escaping is ugly and preferably should not be necessary or even allowed.
> 
> Therefore, I propose, by example:
> 
>   let foo = 
> /"xx
> The indent of /"
> dictates indentation and must match 
> all indents through the "/
> "/xx
> 
> where an optional arbitrary identifier, for example “xx”, can be appended to 
> both the open and the close quote delimiters to avoid the need for escaping 
> the close quote delimiter. The identifier has no other significance in the 
> program.
> 
> I further propose that /' and '/ should be used to delimit a string that is 
> interpreted literally, including newlines except for the newline on the last 
> line of the string.
> 
> In future, consideration should be given to the idea of following the /" 
> delimiter by a set of space-separated flags to determine treatment of 
> newlines, the escape character (so it doesn’t have to be backslash), use of 
> interpolated strings, the use of escape characters, etc.
> 
> Dave
> 
> (I intended all single and double quotes in this message to be ASCII, not 
> curly. If any are curly, then blame the macOS Mail app.)
> 
> [1].  I think Swift should allow delimiting strings with “curly” quotes, and 
> they should nest. See 3, 4, 5 above.
> 
> ___
> 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] Swift run Command

2017-05-15 Thread Robert Widmann via swift-evolution
+1.  A very useful feature to have, indeed.

~Robert Widmann

> On May 15, 2017, at 1:47 AM, David Hart via swift-evolution 
>  wrote:
> 
> Hello evolution (and build-dev),
> 
> I’d like to pitch a QOL proposal to improve the development of command-line 
> Swift Packages by introducing a `swift run` command. I’d value any feedback 
> before moving forward.
> 
> https://github.com/hartbit/swift-evolution/blob/swift-run-command/proposals/-swift-run-command.md
>  
> 
> 
> Regards,
> David.
> 
> Swift run Command
> 
> Proposal: SE- 
> 
> Authors: David Hart 
> Review Manager: TBD
> Status: TBD
>  
> Introduction
> 
> The proposal introduces a new swift run command to build and run an 
> executable defined in the current package.
> 
>  
> Motivation
> 
> It is common to want to build and run an executable during development. For 
> now, one must first build it and then execute it from the build folder:
> 
> $ swift build
> $ .build/debug/myexecutable
> In Swift 4, the Swift Package Manager will build to a different path, 
> containing a platform sub-folder (.build/macosx-x86_64/debug for mac and 
> .build/linux-x86_64/debug for linux), making it more cumbersome to run the 
> executable from the command line.
> 
> To improve the development workflow, the proposal suggest introducing a new 
> first-level swift run command that will build if necessary and then run an 
> executable defined in the Package.swift manifest, replacing the above steps 
> into just one.
> 
>  
> Proposed
>  solution
> 
> The swift run command would be defined as:
> 
> $ swift run --help
> OVERVIEW: Build and run executable
> 
> USAGE: swift run [options] [executable] [-- arguments]
> 
> OPTIONS:
>   --build-pathSpecify build/cache directory [default: ./.build]
>   --chdir, -C Change working directory before any other operation
>   --in-dir, -IChange working directory before running the 
> executable
>   --color Specify color mode (auto|always|never) [default: 
> auto]
>   --configuration, -c Build with configuration (debug|release) [default: 
> debug]
>   --enable-prefetchingEnable prefetching in resolver
>   --skip-buildSkip building the executable product
>   --verbose, -v   Increase verbosity of informational output
>   -XccPass flag through to all C compiler invocations
>   -XlinkerPass flag through to all linker invocations
>   -XswiftcPass flag through to all Swift compiler invocations
>   --help  Display available options
> If needed, the command will build the product before running it. As a result, 
> it can be passed any options swift buildaccepts. As for swift test, it also 
> accepts an extra --skip-build option to skip the build phase. A new 
> --in-diroption is also introduced to run the executable from another 
> directory.
> 
> After the options, the command optionally takes the name of an executable 
> product defined in the Package.swiftmanifest and introduced in SE-0146 
> .
>  If called without an executable and the manifest defines one and only one 
> executable product, it will default to running that one. In any other case, 
> the command fails.
> 
> The executable can be called with arguments by prefixing them with a -- to 
> separate them from the executable name.
> 
>  
> Alternatives
>  considered
> 
> One alternative to the Swift 4 change of build folder would be for the Swift 
> Package Manager to create and update a symlink at .build/debug and 
> .build/release that point to the latest build folder for that configuration. 
> Although that should probably be done to retain backward-compatibility with 
> tools that depended on the build location, it does not completely invalid the 
> usefulness of the run command.
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

___
swift-evolution mailing list
swift-evolution@swift.org

Re: [swift-evolution] [Pitch] Never as a bottom type

2017-05-14 Thread Robert Widmann via swift-evolution


> 
> But it has its limits, most notably, it cannot be used as an expression
> 
> let dunno: Int = fatalError("what should I put here?") // cannot convert 
> value of type 'Never'
> 

Though our type lattice doesn’t necessarily have a bottom in the way you’re 
looking for, you can use Never-returning functions to inhabit a combinator that 
will do this for you.

func undefined() -> A {
fatalError("")
}

> It makes sense because Never is not a bottom type. If it were, this statement 
> would be absolutely valid.
> 
> Having a bottom type and a value for it has several advantages:
> 
> - More informative error messages with forced unwrap:
> 
> protocol WonkyAPI {
> func apiCall() -> Int? //this always return an Int, why is it optional?
> }
> 
> func mycode() {
> let valueFromAPI = apiCall() ?? fatalError("The API used to always return 
> a value, but now it does not!")
> …
> }
> 
> It sometimes happen that some part of the code uses an optional but in your 
> particular codepath, the optional is always containing a value (for example 
> after an assignment).
> As of today, you can write
> guard let value = value else { fatalError("something terrible happened") }
> for the same effect with a more verbose syntax.
> 
> - Use as a hole/placeholder during development
> During development it is very likely that you will want to write a piece of 
> functionality but be stuck on an intermediate part of the computation. Assume 
> we have an identifier `undefined` of type `Never` which would represent an 
> impossible value as a bottom type. We would ben able to write:
> 
> func transform(point: CGPoint) -> CGPoint {
> let translation =  Matrix3D(1, 0, 2,
> 0, 1, -2,
> 0, 0, 1)
> let rotation: Matrix3D = undefined //what was it? I forgot
> return (translation * rotation * point.homogenous).toPoint()
> }
> 
> We can debate on the right naming for undefined. Haskell uses 'undefined', 
> Scala uses `???`. `unimplemented`, `impossible`, `void`are all valid 
> contenders.
> 
> - Eliminate type annotations for generic covariant types
> As of today this is not valid 
> 
> struct Person {
> let name: String
> }
> 
> var maybeSomeone = nil
> maybeSomeone = Person(name: "Doug”)
> 
> Even though it is clear that maybeSomeone is of type Optional.
> That is because the compiler cannot guess which type the Optional wraps when 
> `maybeSomeone` is declared. But with a bottom type, a naked nil can be mapped 
> to `Optional` until the type inference figures out from the context 
> what is the type of Optional. If it cannot because no use or no assignment is 
> done, the compiler could emit an “unreachable” warning just like it does for 
> 
> func unreach() {
> fatalError("stop here")
> print("not printed”) // warning: will never be executed
> }
> 
> Should I write a proposal?
> 
> André Videla
> ___
> 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] [Proposal][Discussion] Deprecate Tuple Shuffles

2017-05-05 Thread Robert Widmann via swift-evolution


~Robert Widmann

2017/05/05 14:07、John McCall <rjmcc...@apple.com> のメッセージ:

>> On May 4, 2017, at 10:52 PM, Robert Widmann via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> - Parse: Has to account for the inclusion of tuple shuffles whenever it 
>> parses patterns (see the switch-statement example in the proposal)
> 
> This example doesn't make any sense.  Tuple shuffles are not responsible for 
> the rule that you cannot match an unlabelled tuple with a labelled tuple 
> pattern.  I'm really not sure what you think this would do, anyway; it's not 
> like tuple pattern element labels are lexically available.
> 

Exactly. I've since removed this example.  My initial confusion was around the 
labeled matching being a thing at all. 

>> - Sema: Has to perform argument matching by computing these tuple shuffle 
>> mappings thereby complicating the solver and the parts of solution 
>> application.  Really, the only place this has a valid use is in the error 
>> handling path where we can use the tuple shuffle to emit a fixit that 
>> properly reorders arguments - something we should be doing even today.  
>> Tuple shuffles are also allowed to reorder around variadic arguments which 
>> makes matching that much more difficult.
> 
> The type-checker doesn't have to do this with argument-matching.  It might do 
> it anyway, but it doesn't have to.
> 
>> - SIL: Has to account for tuple shuffles in multiple places.  One notable 
>> one is that SILGen has to support two different paths when lowering tuple 
>> shuffles - one for variadic shuffles and the other for “normal” shuffles.  
>> Each path supports a different subset of the features necessary to implement 
>> the full feature that is tuple shuffles, neither can really be simplified 
>> down to a common core in their current iteration.
> 
> Call argument emission needs to deal with something like this anyway.  But 
> yes, we could eliminate the redundant path for ordinary r-value tuple 
> emission.
> 
> I'm not saying any of this to kill this proposal, just to clarify that the 
> complexity costs aren't as high as you seem to be saying.
> 
> John.
> 
>> If you want some numbers, I spent the evening removing them from the 
>> codebase and came up with a win of about 1500 LoC.  Each line of code 
>> supporting a feature that people aren’t actually using.
>> 
>> ~Robert Widmann
>> 
>> 
>>>> On May 4, 2017, at 10:35 PM, Tony Arnold via swift-evolution 
>>>> <swift-evolution@swift.org> wrote:
>>>> 
>>>> 
>>>> On 5 May 2017, at 12:27, Félix Cloutier via swift-evolution 
>>>> <swift-evolution@swift.org> wrote:
>>>> 
>>>> Why?
>>> 
>>> Not trying to be smart, but the reasoning is in Robert’s proposal:
>>> 
>>>>> Their inclusion in the language complicates every part of the compiler 
>>>>> stack, uses a syntax that can be confused for type annotations 
>>>>> (https://twitter.com/CodaFi_/status/860246169854894081), contradicts the 
>>>>> goals of earlier SE's (see SE-0060), and makes non-sensical patterns 
>>>>> possible in surprising places.
>>> 
>>> 
>>> Robert, maybe you could include some detail about how this feature is 
>>> complicating the compiler stack, and what will be improved by it’s removal?
>>> 
>>> 
>>> 
>>> That being said, I’m all for you guys making your lives easier at the cost 
>>> of something we shouldn’t be using in the first place…
>>> 
>>> 
>>> Tony
>>> 
>>> 
>>> --
>>> Tony Arnold
>>> +61 411 268 532
>>> http://thecocoabots.com/
>>> 
>>> ABN: 14831833541
>>> 
>>> ___
>>> 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] [Proposal][Discussion] Deprecate Tuple Shuffles

2017-05-05 Thread Robert Widmann via swift-evolution
st prohibiting tuple shuffling, and I'm rather 
>>>> disappointed that you described such a dramatic change using a corner 
>>>> case. There are very good reasons why someone finds 'let (y: x, x: y) = 
>>>> (x: 1, y: 2)' confusing and would support its removal, but it is entirely 
>>>> another ballgame to remove labels from tuple patterns altogether.
>>>> 
>>>> 
>>>> On Thu, May 4, 2017 at 23:47 Xiaodi Wu <xiaodi...@gmail.com 
>>>> <mailto:xiaodi...@gmail.com>> wrote:
>>>> Now I'm confused. The ordinary meaning of the word "shuffle" is not 
>>>> changing but rather reordering, and all of your examples are of reordering.
>>>> 
>>>> To be clear, are you proposing the prohibition of *adding or removing* 
>>>> labels as well? A previous discussion on tuple shuffling on this list saw 
>>>> consensus that assigning a value of type (label1: T, label2: U) to a 
>>>> variable of type (T, U) and vice versa should absolutely be supported, 
>>>> whether or not reordering is permitted.
>>>> 
>>>> And how about *restating* existing labels without any adding or removing? 
>>>> To be clear:
>>>> 
>>>> ```
>>>> let (partialValue: v, overflow: o) = 42.addingReportingOverflow(42)
>>>> ```
>>>> 
>>>> ...involves absolutely no changes in labels whatsoever. The return type is 
>>>> (partialValue: Int, overflow: ArithmeticOverflow).
>>>> 
>>>> Either one of these scenarios is commonly used, and it is astonishing to 
>>>> me that they would be eliminated.
>>>> 
>>>> On Thu, May 4, 2017 at 23:28 Robert Widmann <devteam.cod...@gmail.com 
>>>> <mailto:devteam.cod...@gmail.com>> wrote:
>>>> That doesn't involve a parameter reordering, but because it changes 
>>>> argument labels it's a shuffle.
>>>> 
>>>> ~Robert Widmann
>>>> 
>>>> 2017/05/05 0:16、Xiaodi Wu <xiaodi...@gmail.com 
>>>> <mailto:xiaodi...@gmail.com>> のメッセージ:
>>>> 
>>>>> Robert,
>>>>> 
>>>>> As I mentioned on Twitter, getting rid of tuple shuffles would not cure 
>>>>> your example, which does not involve a shuffle. Unless you're proposing 
>>>>> to disallow the use of labels during destructuring entirely, which I 
>>>>> would think to be very much unacceptable. Example:
>>>>> 
>>>>> ```
>>>>> let (partialValue: v, overflow: o) = 42.addingReportingOverflow(42)
>>>>> ```
>>>>> 
>>>>> This involves no shuffling and should absolutely remain allowed.
>>>>> 
>>>>> 
>>>>> On Thu, May 4, 2017 at 21:15 Robert Widmann via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> Hi all,
>>>>> 
>>>>> So sorry that this proposal comes so late in the game, but I feel it’s 
>>>>> too important not to bring it to the attention of the community now.  
>>>>> Attached is a proposal to deprecate a language feature many of you will 
>>>>> probably have never had the chance to use: Tuple Shuffles.  I’ve attached 
>>>>> a copy of the first draft of the proposal below, but the latest copy can 
>>>>> be read on Github 
>>>>> <https://github.com/apple/swift-evolution/pull/705/files>.
>>>>> 
>>>>> Thanks!
>>>>> 
>>>>> ~Robert Widmann
>>>>> 
>>>>> Deprecate Tuple Shuffles
>>>>> 
>>>>> Proposal: SE- 
>>>>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/-filename.md>
>>>>> Authors: Robert Widmann <https://github.com/codafi>
>>>>> Review Manager: TBD
>>>>> Status: Awaiting review
>>>>>  
>>>>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/-deprecate-tuple-shuffles.md#introduction>Introduction
>>>>> 
>>>>> This proposal seeks the deprecation of a little-known feature of Swift 
>>>>> called a "Tuple Shuffle".
>>>>> 
>>>>>  
>>>>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/

Re: [swift-evolution] [Proposal][Discussion] Deprecate Tuple Shuffles

2017-05-05 Thread Robert Widmann via swift-evolution
To clarify for the root.  Disregard the “Detailed Design” section attached to 
this email.  The proposal on Github no longer seeks to remove labeled tuple 
patterns from the language.


> On May 4, 2017, at 10:14 PM, Robert Widmann  wrote:
> 
> Hi all,
> 
> So sorry that this proposal comes so late in the game, but I feel it’s too 
> important not to bring it to the attention of the community now.  Attached is 
> a proposal to deprecate a language feature many of you will probably have 
> never had the chance to use: Tuple Shuffles.  I’ve attached a copy of the 
> first draft of the proposal below, but the latest copy can be read on Github 
> .
> 
> Thanks!
> 
> ~Robert Widmann
> 
> Deprecate Tuple Shuffles
> 
> Proposal: SE- 
> 
> Authors: Robert Widmann 
> Review Manager: TBD
> Status: Awaiting review
>  
> Introduction
> 
> This proposal seeks the deprecation of a little-known feature of Swift called 
> a "Tuple Shuffle".
> 
>  
> Motivation
> 
> A tuple-shuffle is an undocumented feature of Swift in which one can re-order 
> the indices of a tuple by writing a pattern that describes a permutation in a 
> syntax reminiscent of adding type-annotations to a parameter list:
> 
> let a = (x: 1, y: 2)
> var b: (y: Int, x: Int)
> b = a
> It can be used to simultaneously destructure and reorder a tuple:
> 
> let tuple = (first: 0, second: (x: 1, y: 2))
> let (second: (x: b, y: c), first: a) = tuple
> It can also be used to map parameter labels out of order in a call expression:
> 
> func foo(_ : (x : Int, y : Int)) {}
> foo((y: 5, x: 10)) // Valid
> Note that a tuple shuffle is distinct from a re-assignment through a tuple 
> pattern. For example, this series of statements will continue to function as 
> before:
> 
> var x = 5
> var y = 10
> var z = 15
> (z, y, x) = (x, z, y)
> Their inclusion in the language complicates every part of the compiler stack, 
> uses a syntax that can be confused for type annotations 
> , contradicts the 
> goals of earlier SE's (see SE-0060 
> ),
>  and makes non-sensical patterns possible in surprising places.
> 
> Take switch-statements, for example:
> 
> switch ((0, 0), 0){ 
> case (_ : let (y, z), _ : let s): () // We are forbidden from giving these 
> patterns names other than "_" 
> default: () 
> }
> This proposal seeks to deprecate them in Swift 3 compatibility mode and 
> enforce that deprecation as a hard error in Swift 4 to facilitate their 
> eventual removal from the language.
> 
>  
> Proposed
>  solution
> 
> Construction of Tuple Shuffle Expressions will become a warning in Swift 3 
> compatibility mode and will be a hard-error in Swift 4.
> 
>  
> Detailed
>  design
> 
> In addition to the necessary diagnostics, the grammar will be ammended to 
> simplify the following productions:
> 
> tuple-pattern → (tuple-pattern-element-list )
> tuple-pattern-element-list → tuple-pattern-element | tuple-pattern-element , 
> tuple-pattern-element-list
> - tuple-pattern-element → pattern | identifier:pattern
> + tuple-pattern-element → pattern
>  
> Impact
>  on Existing Code
> 
> Because very little code is intentionally using Tuple Shuffles, impact on 
> existing code will be negligible but not non-zero.
> 
>  
> Alternatives
>  considered
> 
> Continue to keep the architecture in place to facilitate this feature.

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


Re: [swift-evolution] [Proposal][Discussion] Deprecate Tuple Shuffles

2017-05-05 Thread Robert Widmann via swift-evolution
st prohibiting tuple shuffling, and I'm rather 
>>>> disappointed that you described such a dramatic change using a corner 
>>>> case. There are very good reasons why someone finds 'let (y: x, x: y) = 
>>>> (x: 1, y: 2)' confusing and would support its removal, but it is entirely 
>>>> another ballgame to remove labels from tuple patterns altogether.
>>>> 
>>>> 
>>>> On Thu, May 4, 2017 at 23:47 Xiaodi Wu <xiaodi...@gmail.com 
>>>> <mailto:xiaodi...@gmail.com>> wrote:
>>>> Now I'm confused. The ordinary meaning of the word "shuffle" is not 
>>>> changing but rather reordering, and all of your examples are of reordering.
>>>> 
>>>> To be clear, are you proposing the prohibition of *adding or removing* 
>>>> labels as well? A previous discussion on tuple shuffling on this list saw 
>>>> consensus that assigning a value of type (label1: T, label2: U) to a 
>>>> variable of type (T, U) and vice versa should absolutely be supported, 
>>>> whether or not reordering is permitted.
>>>> 
>>>> And how about *restating* existing labels without any adding or removing? 
>>>> To be clear:
>>>> 
>>>> ```
>>>> let (partialValue: v, overflow: o) = 42.addingReportingOverflow(42)
>>>> ```
>>>> 
>>>> ...involves absolutely no changes in labels whatsoever. The return type is 
>>>> (partialValue: Int, overflow: ArithmeticOverflow).
>>>> 
>>>> Either one of these scenarios is commonly used, and it is astonishing to 
>>>> me that they would be eliminated.
>>>> 
>>>> On Thu, May 4, 2017 at 23:28 Robert Widmann <devteam.cod...@gmail.com 
>>>> <mailto:devteam.cod...@gmail.com>> wrote:
>>>> That doesn't involve a parameter reordering, but because it changes 
>>>> argument labels it's a shuffle.
>>>> 
>>>> ~Robert Widmann
>>>> 
>>>> 2017/05/05 0:16、Xiaodi Wu <xiaodi...@gmail.com 
>>>> <mailto:xiaodi...@gmail.com>> のメッセージ:
>>>> 
>>>>> Robert,
>>>>> 
>>>>> As I mentioned on Twitter, getting rid of tuple shuffles would not cure 
>>>>> your example, which does not involve a shuffle. Unless you're proposing 
>>>>> to disallow the use of labels during destructuring entirely, which I 
>>>>> would think to be very much unacceptable. Example:
>>>>> 
>>>>> ```
>>>>> let (partialValue: v, overflow: o) = 42.addingReportingOverflow(42)
>>>>> ```
>>>>> 
>>>>> This involves no shuffling and should absolutely remain allowed.
>>>>> 
>>>>> 
>>>>> On Thu, May 4, 2017 at 21:15 Robert Widmann via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> Hi all,
>>>>> 
>>>>> So sorry that this proposal comes so late in the game, but I feel it’s 
>>>>> too important not to bring it to the attention of the community now.  
>>>>> Attached is a proposal to deprecate a language feature many of you will 
>>>>> probably have never had the chance to use: Tuple Shuffles.  I’ve attached 
>>>>> a copy of the first draft of the proposal below, but the latest copy can 
>>>>> be read on Github 
>>>>> <https://github.com/apple/swift-evolution/pull/705/files>.
>>>>> 
>>>>> Thanks!
>>>>> 
>>>>> ~Robert Widmann
>>>>> 
>>>>> Deprecate Tuple Shuffles
>>>>> 
>>>>> Proposal: SE- 
>>>>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/-filename.md>
>>>>> Authors: Robert Widmann <https://github.com/codafi>
>>>>> Review Manager: TBD
>>>>> Status: Awaiting review
>>>>>  
>>>>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/-deprecate-tuple-shuffles.md#introduction>Introduction
>>>>> 
>>>>> This proposal seeks the deprecation of a little-known feature of Swift 
>>>>> called a "Tuple Shuffle".
>>>>> 
>>>>>  
>>>>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/pr

Re: [swift-evolution] [Proposal][Discussion] Deprecate Tuple Shuffles

2017-05-05 Thread Robert Widmann via swift-evolution
ArithmeticOverflow).
>>>> 
>>>> That, however, is a kind of shuffle I intend to deprecate here.  This kind 
>>>> of pattern is subject to the “arcane syntax” part of the proposal.
>>>> 
>>>>>> 
>>>>>> Either one of these scenarios is commonly used, and it is astonishing to 
>>>>>> me that they would be eliminated.
>>>> 
>>>> Do you have proof of that claim? I have never seen the relevant kinds of 
>>>> tuple shuffle used before, and I doubt you have either before today.
>>> 
>>> Huh? I use it pervasively. Currently, writing out labels during 
>>> destructuring guarantees that, even if I've incorrectly memorized the order 
>>> of the values in a tuple, the tuple is still destructured as I expect. And 
>>> if reordering were not a feature of Swift, I would still write out these 
>>> labels. In that case, it would be a static assertion that destructuring is 
>>> happening in the expected order. That is, if I try to destructure a tuple 
>>> of type (r: Int, g: Int, b: Int, a: Int) and accidentally write 'let (a: 
>>> alpha, r: _, g: green, b: _) = ...', I'd get an error and find my mistake 
>>> at compile time.
>>> 
>>> The whole point of having labels in the first place is clarity at the point 
>>> of use. Just as SE-0111 will need revision because it removed a key 
>>> documentation use for argument labels, forbidding labels in tuple patterns 
>>> would make the same mistake for tuples.
>> 
>> The intent at the time may have been to treat tuples as a kind of 
>> structurally-typed thing, but shadowing concerns and reordering in patterns 
>> means this kind of relabeling can be abused and shouldn't be trusted as a 
>> kind of structural invariant in a pattern - as we seem to agree.  To me, 
>> labels in tuple types provide a means of defining custom projections out of 
>> the tuple, nothing more.  In patterns, I don't see a reason for them.
> 
> We can agree that relabeling can be abused, but it does not stand to reason 
> that labeling (i.e. the correct, unchanged label) has no role in tuple 
> patterns. Again, it serves as documentation for the pattern, just as labels 
> serve as documentation for tuples, enum cases, and functions. There are many 
> languages that see no reason for labels at all, but Swift is not one of those 
> languages.
> 
>> 
>>> 
>>>> 
>>>> ~Robert Widmann
>>>> 
>>>>> On May 5, 2017, at 12:53 AM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
>>>>> 
>>>>> Ah, I see from your proposed grammar update: you're proposing to prohibit 
>>>>> the use of labels entirely in a tuple pattern.
>>>>> 
>>>>> This is much more than just prohibiting tuple shuffling, and I'm rather 
>>>>> disappointed that you described such a dramatic change using a corner 
>>>>> case. There are very good reasons why someone finds 'let (y: x, x: y) = 
>>>>> (x: 1, y: 2)' confusing and would support its removal, but it is entirely 
>>>>> another ballgame to remove labels from tuple patterns altogether.
>>>>> 
>>>>> 
>>>>>> On Thu, May 4, 2017 at 23:47 Xiaodi Wu <xiaodi...@gmail.com> wrote:
>>>>>> Now I'm confused. The ordinary meaning of the word "shuffle" is not 
>>>>>> changing but rather reordering, and all of your examples are of 
>>>>>> reordering.
>>>>>> 
>>>>>> To be clear, are you proposing the prohibition of *adding or removing* 
>>>>>> labels as well? A previous discussion on tuple shuffling on this list 
>>>>>> saw consensus that assigning a value of type (label1: T, label2: U) to a 
>>>>>> variable of type (T, U) and vice versa should absolutely be supported, 
>>>>>> whether or not reordering is permitted.
>>>>>> 
>>>>>> And how about *restating* existing labels without any adding or 
>>>>>> removing? To be clear:
>>>>>> 
>>>>>> ```
>>>>>> let (partialValue: v, overflow: o) = 42.addingReportingOverflow(42)
>>>>>> ```
>>>>>> 
>>>>>> ...involves absolutely no changes in labels whatsoever. The return type 
>>>>>> is (partialValue: Int, overflow: ArithmeticOverflow).
>>>>>> 
>>>>>> Either one of these scenarios is commonly used, and it is astonishing to 
>

Re: [swift-evolution] [Proposal][Discussion] Deprecate Tuple Shuffles

2017-05-05 Thread Robert Widmann via swift-evolution
 
means this kind of relabeling can be abused and shouldn't be trusted as a kind 
of structural invariant in a pattern - as we seem to agree.  To me, labels in 
tuple types provide a means of defining custom projections out of the tuple, 
nothing more.  In patterns, I don't see a reason for them.

> 
>> 
>> ~Robert Widmann
>> 
>>> On May 5, 2017, at 12:53 AM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
>>> 
>>> Ah, I see from your proposed grammar update: you're proposing to prohibit 
>>> the use of labels entirely in a tuple pattern.
>>> 
>>> This is much more than just prohibiting tuple shuffling, and I'm rather 
>>> disappointed that you described such a dramatic change using a corner case. 
>>> There are very good reasons why someone finds 'let (y: x, x: y) = (x: 1, y: 
>>> 2)' confusing and would support its removal, but it is entirely another 
>>> ballgame to remove labels from tuple patterns altogether.
>>> 
>>> 
>>>> On Thu, May 4, 2017 at 23:47 Xiaodi Wu <xiaodi...@gmail.com> wrote:
>>>> Now I'm confused. The ordinary meaning of the word "shuffle" is not 
>>>> changing but rather reordering, and all of your examples are of reordering.
>>>> 
>>>> To be clear, are you proposing the prohibition of *adding or removing* 
>>>> labels as well? A previous discussion on tuple shuffling on this list saw 
>>>> consensus that assigning a value of type (label1: T, label2: U) to a 
>>>> variable of type (T, U) and vice versa should absolutely be supported, 
>>>> whether or not reordering is permitted.
>>>> 
>>>> And how about *restating* existing labels without any adding or removing? 
>>>> To be clear:
>>>> 
>>>> ```
>>>> let (partialValue: v, overflow: o) = 42.addingReportingOverflow(42)
>>>> ```
>>>> 
>>>> ...involves absolutely no changes in labels whatsoever. The return type is 
>>>> (partialValue: Int, overflow: ArithmeticOverflow).
>>>> 
>>>> Either one of these scenarios is commonly used, and it is astonishing to 
>>>> me that they would be eliminated.
>>>> 
>>>>> On Thu, May 4, 2017 at 23:28 Robert Widmann <devteam.cod...@gmail.com> 
>>>>> wrote:
>>>>> That doesn't involve a parameter reordering, but because it changes 
>>>>> argument labels it's a shuffle.
>>>>> 
>>>>> ~Robert Widmann
>>>>> 
>>>>> 2017/05/05 0:16、Xiaodi Wu <xiaodi...@gmail.com> のメッセージ:
>>>>> 
>>>>>> Robert,
>>>>>> 
>>>>>> As I mentioned on Twitter, getting rid of tuple shuffles would not cure 
>>>>>> your example, which does not involve a shuffle. Unless you're proposing 
>>>>>> to disallow the use of labels during destructuring entirely, which I 
>>>>>> would think to be very much unacceptable. Example:
>>>>>> 
>>>>>> ```
>>>>>> let (partialValue: v, overflow: o) = 42.addingReportingOverflow(42)
>>>>>> ```
>>>>>> 
>>>>>> This involves no shuffling and should absolutely remain allowed.
>>>>>> 
>>>>>> 
>>>>>>> On Thu, May 4, 2017 at 21:15 Robert Widmann via swift-evolution 
>>>>>>> <swift-evolution@swift.org> wrote:
>>>>>>> Hi all,
>>>>>>> 
>>>>>>> So sorry that this proposal comes so late in the game, but I feel it’s 
>>>>>>> too important not to bring it to the attention of the community now.  
>>>>>>> Attached is a proposal to deprecate a language feature many of you will 
>>>>>>> probably have never had the chance to use: Tuple Shuffles.  I’ve 
>>>>>>> attached a copy of the first draft of the proposal below, but the 
>>>>>>> latest copy can be read on Github.
>>>>>>> 
>>>>>>> Thanks!
>>>>>>> 
>>>>>>> ~Robert Widmann
>>>>>>> 
>>>>>>> Deprecate Tuple Shuffles
>>>>>>> Proposal: SE-
>>>>>>> Authors: Robert Widmann
>>>>>>> Review Manager: TBD
>>>>>>> Status: Awaiting review
>>>>>>> Introduction
>>>>>>> 
>>>>>>> This proposal seeks the dep

Re: [swift-evolution] [Proposal][Discussion] Deprecate Tuple Shuffles

2017-05-04 Thread Robert Widmann via swift-evolution
None of those are affected.  See the note in the proposal.

~Robert Widmann

> On May 5, 2017, at 1:16 AM, Adrian Zubarev <adrian.zuba...@devandartist.com> 
> wrote:
> 
> Hi Robert,
> 
> I’m trying to understand the impact of your proposal and the feature you want 
> to remove from the language. Could you describe a little more on how if ever 
> this affects tuple destructuring? 
> 
> var (a, b, c) = (0, "", 0)
> 
> (a, b) = (42, "Hello Swift")
> 
> (a = 42, b = "Hello Swift")
> 
> var (x, y) = (0, 42)
> 
> (x, y) = (y, x) // swap without a temporary value
> 
> 
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> 
> Am 5. Mai 2017 um 04:15:12, Robert Widmann via swift-evolution 
> (swift-evolution@swift.org <mailto:swift-evolution@swift.org>) schrieb:
> 
>> Hi all,
>> 
>> So sorry that this proposal comes so late in the game, but I feel it’s too 
>> important not to bring it to the attention of the community now.  Attached 
>> is a proposal to deprecate a language feature many of you will probably have 
>> never had the chance to use: Tuple Shuffles.  I’ve attached a copy of the 
>> first draft of the proposal below, but the latest copy can be read on Github 
>> <https://github.com/apple/swift-evolution/pull/705/files>.
>> 
>> Thanks!
>> 
>> ~Robert Widmann
>> 
>> Deprecate Tuple Shuffles
>> Proposal: SE- 
>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/-filename.md>
>> Authors: Robert Widmann <https://github.com/codafi>
>> Review Manager: TBD
>> Status: Awaiting review
>>  
>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/-deprecate-tuple-shuffles.md#introduction>Introduction
>> 
>> This proposal seeks the deprecation of a little-known feature of Swift 
>> called a "Tuple Shuffle".
>> 
>>  
>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/-deprecate-tuple-shuffles.md#motivation>Motivation
>> 
>> A tuple-shuffle is an undocumented feature of Swift in which one can 
>> re-order the indices of a tuple by writing a pattern that describes a 
>> permutation in a syntax reminiscent of adding type-annotations to a 
>> parameter list:
>> 
>> let a = (x: 1, y: 2)
>> var b: (y: Int, x: Int)
>> b = a
>> It can be used to simultaneously destructure and reorder a tuple:
>> 
>> let tuple = (first: 0, second: (x: 1, y: 2))
>> let (second: (x: b, y: c), first: a) = tuple
>> It can also be used to map parameter labels out of order in a call 
>> expression:
>> 
>> func foo(_ : (x : Int, y : Int)) {}
>> foo((y: 5, x: 10)) // Valid
>> Note that a tuple shuffle is distinct from a re-assignment through a tuple 
>> pattern. For example, this series of statements will continue to function as 
>> before:
>> 
>> var x = 5
>> var y = 10
>> var z = 15
>> (z, y, x) = (x, z, y)
>> Their inclusion in the language complicates every part of the compiler 
>> stack, uses a syntax that can be confused for type annotations 
>> <https://twitter.com/CodaFi_/status/860246169854894081>, contradicts the 
>> goals of earlier SE's (see SE-0060 
>> <https://github.com/apple/swift-evolution/blob/9cf2685293108ea3efcbebb7ee6a8618b83d4a90/proposals/0060-defaulted-parameter-order.md>),
>>  and makes non-sensical patterns possible in surprising places.
>> 
>> Take switch-statements, for example:
>> 
>> switch ((0, 0), 0){  
>> case (_ : let (y, z), _ : let s): () // We are forbidden from giving these 
>> patterns names other than "_" 
>> default: ()  
>> }
>> This proposal seeks to deprecate them in Swift 3 compatibility mode and 
>> enforce that deprecation as a hard error in Swift 4 to facilitate their 
>> eventual removal from the language.
>> 
>>  
>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/-deprecate-tuple-shuffles.md#proposed-solution>Proposed
>>  solution
>> 
>> Construction of Tuple Shuffle Expressions will become a warning in Swift 3 
>> compatibility mode and will be a hard-error in Swift 4.
>> 
>>  
>> <https://github.com/CodaFi/swift-evolution/blob/8eaf320b3c2a117909fc0269c398e89c033a4b9f/proposals/-deprecate-tuple-shuffles.md#detailed-design>Detailed
>>  design
>> 
>> In addition to the necessary diagnostics, the g

Re: [swift-evolution] [Proposal][Discussion] Deprecate Tuple Shuffles

2017-05-04 Thread Robert Widmann via swift-evolution
On the contrary, this is precisely what it means to deprecate tuple shuffles.  
You can’t map common parlance onto this term; the proposal and the Twitter 
thread weren’t merely about reordering arguments.

> but it is entirely another ballgame to remove labels from tuple patterns 
> altogether.

It’s really not.  Let me demonstrate:

> To be clear, are you proposing the prohibition of *adding or removing* labels 
> as well? A previous discussion on tuple shuffling on this list saw consensus 
> that assigning a value of type (label1: T, label2: U) to a variable of type 
> (T, U) and vice versa should absolutely be supported, whether or not 
> reordering is permitted.

I am not proposing any changes to switching parameter labels through well-typed 
re-assignments.  This is absolutely still going to be allowed:

var z : (Int, Int) = (0, 0)
var w : (x : Int, y : Int) = (5, 10)
z = w
w = z

This is modeled internally with a tuple shuffle, but not the kind of shuffle 
I’m interested in banning.  It’s a far simpler kind of 

> And how about *restating* existing labels without any adding or removing? To 
> be clear:
> 
> ```
> let (partialValue: v, overflow: o) = 42.addingReportingOverflow(42)
> ```
> 
> ...involves absolutely no changes in labels whatsoever. The return type is 
> (partialValue: Int, overflow: ArithmeticOverflow).

That, however, is a kind of shuffle I intend to deprecate here.  This kind of 
pattern is subject to the “arcane syntax” part of the proposal.

> 
> Either one of these scenarios is commonly used, and it is astonishing to me 
> that they would be eliminated.

Do you have proof of that claim? I have never seen the relevant kinds of tuple 
shuffle used before, and I doubt you have either before today.

~Robert Widmann

> On May 5, 2017, at 12:53 AM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> Ah, I see from your proposed grammar update: you're proposing to prohibit the 
> use of labels entirely in a tuple pattern.
> 
> This is much more than just prohibiting tuple shuffling, and I'm rather 
> disappointed that you described such a dramatic change using a corner case. 
> There are very good reasons why someone finds 'let (y: x, x: y) = (x: 1, y: 
> 2)' confusing and would support its removal, but it is entirely another 
> ballgame to remove labels from tuple patterns altogether.
> 
> 
> On Thu, May 4, 2017 at 23:47 Xiaodi Wu <xiaodi...@gmail.com 
> <mailto:xiaodi...@gmail.com>> wrote:
> Now I'm confused. The ordinary meaning of the word "shuffle" is not changing 
> but rather reordering, and all of your examples are of reordering.
> 
> To be clear, are you proposing the prohibition of *adding or removing* labels 
> as well? A previous discussion on tuple shuffling on this list saw consensus 
> that assigning a value of type (label1: T, label2: U) to a variable of type 
> (T, U) and vice versa should absolutely be supported, whether or not 
> reordering is permitted.
> 
> And how about *restating* existing labels without any adding or removing? To 
> be clear:
> 
> ```
> let (partialValue: v, overflow: o) = 42.addingReportingOverflow(42)
> ```
> 
> ...involves absolutely no changes in labels whatsoever. The return type is 
> (partialValue: Int, overflow: ArithmeticOverflow).
> 
> Either one of these scenarios is commonly used, and it is astonishing to me 
> that they would be eliminated.
> 
> On Thu, May 4, 2017 at 23:28 Robert Widmann <devteam.cod...@gmail.com 
> <mailto:devteam.cod...@gmail.com>> wrote:
> That doesn't involve a parameter reordering, but because it changes argument 
> labels it's a shuffle.
> 
> ~Robert Widmann
> 
> 2017/05/05 0:16、Xiaodi Wu <xiaodi...@gmail.com <mailto:xiaodi...@gmail.com>> 
> のメッセージ:
> 
>> Robert,
>> 
>> As I mentioned on Twitter, getting rid of tuple shuffles would not cure your 
>> example, which does not involve a shuffle. Unless you're proposing to 
>> disallow the use of labels during destructuring entirely, which I would 
>> think to be very much unacceptable. Example:
>> 
>> ```
>> let (partialValue: v, overflow: o) = 42.addingReportingOverflow(42)
>> ```
>> 
>> This involves no shuffling and should absolutely remain allowed.
>> 
>> 
>> On Thu, May 4, 2017 at 21:15 Robert Widmann via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> Hi all,
>> 
>> So sorry that this proposal comes so late in the game, but I feel it’s too 
>> important not to bring it to the attention of the community now.  Attached 
>> is a proposal to deprecate a language feature many of you will probably have 
>> never had the chance to use: 

Re: [swift-evolution] [Proposal][Discussion] Deprecate Tuple Shuffles

2017-05-04 Thread Robert Widmann via swift-evolution
That doesn't involve a parameter reordering, but because it changes argument 
labels it's a shuffle.

~Robert Widmann

2017/05/05 0:16、Xiaodi Wu <xiaodi...@gmail.com> のメッセージ:

> Robert,
> 
> As I mentioned on Twitter, getting rid of tuple shuffles would not cure your 
> example, which does not involve a shuffle. Unless you're proposing to 
> disallow the use of labels during destructuring entirely, which I would think 
> to be very much unacceptable. Example:
> 
> ```
> let (partialValue: v, overflow: o) = 42.addingReportingOverflow(42)
> ```
> 
> This involves no shuffling and should absolutely remain allowed.
> 
> 
>> On Thu, May 4, 2017 at 21:15 Robert Widmann via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> Hi all,
>> 
>> So sorry that this proposal comes so late in the game, but I feel it’s too 
>> important not to bring it to the attention of the community now.  Attached 
>> is a proposal to deprecate a language feature many of you will probably have 
>> never had the chance to use: Tuple Shuffles.  I’ve attached a copy of the 
>> first draft of the proposal below, but the latest copy can be read on Github.
>> 
>> Thanks!
>> 
>> ~Robert Widmann
>> 
>> Deprecate Tuple Shuffles
>> Proposal: SE-
>> Authors: Robert Widmann
>> Review Manager: TBD
>> Status: Awaiting review
>> Introduction
>> 
>> This proposal seeks the deprecation of a little-known feature of Swift 
>> called a "Tuple Shuffle".
>> 
>> Motivation
>> 
>> A tuple-shuffle is an undocumented feature of Swift in which one can 
>> re-order the indices of a tuple by writing a pattern that describes a 
>> permutation in a syntax reminiscent of adding type-annotations to a 
>> parameter list:
>> 
>> let a = (x: 1, y: 2)
>> var b: (y: Int, x: Int)
>> b = a
>> It can be used to simultaneously destructure and reorder a tuple:
>> 
>> let tuple = (first: 0, second: (x: 1, y: 2))
>> let (second: (x: b, y: c), first: a) = tuple
>> It can also be used to map parameter labels out of order in a call 
>> expression:
>> 
>> func foo(_ : (x : Int, y : Int)) {}
>> foo((y: 5, x: 10)) // Valid
>> Note that a tuple shuffle is distinct from a re-assignment through a tuple 
>> pattern. For example, this series of statements will continue to function as 
>> before:
>> 
>> var x = 5
>> var y = 10
>> var z = 15
>> (z, y, x) = (x, z, y)
>> Their inclusion in the language complicates every part of the compiler 
>> stack, uses a syntax that can be confused for type annotations, contradicts 
>> the goals of earlier SE's (see SE-0060), and makes non-sensical patterns 
>> possible in surprising places.
>> 
>> Take switch-statements, for example:
>> 
>> switch ((0, 0), 0){ 
>> case (_ : let (y, z), _ : let s): () // We are forbidden from giving these 
>> patterns names other than "_" 
>> default: () 
>> }
>> This proposal seeks to deprecate them in Swift 3 compatibility mode and 
>> enforce that deprecation as a hard error in Swift 4 to facilitate their 
>> eventual removal from the language.
>> 
>> Proposed solution
>> 
>> Construction of Tuple Shuffle Expressions will become a warning in Swift 3 
>> compatibility mode and will be a hard-error in Swift 4.
>> 
>> Detailed design
>> 
>> In addition to the necessary diagnostics, the grammar will be ammended to 
>> simplify the following productions:
>> 
>> tuple-pattern → (tuple-pattern-element-list )
>> tuple-pattern-element-list → tuple-pattern-element | tuple-pattern-element , 
>> tuple-pattern-element-list
>> - tuple-pattern-element → pattern | identifier:pattern
>> + tuple-pattern-element → pattern
>> Impact on Existing Code
>> 
>> Because very little code is intentionally using Tuple Shuffles, impact on 
>> existing code will be negligible but not non-zero.
>> 
>> Alternatives considered
>> 
>> Continue to keep the architecture in place to facilitate this feature.
>> ___
>> 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] [Proposal][Discussion] Deprecate Tuple Shuffles

2017-05-04 Thread Robert Widmann via swift-evolution
- Parse: Has to account for the inclusion of tuple shuffles whenever it parses 
patterns (see the switch-statement example in the proposal)
- Sema: Has to perform argument matching by computing these tuple shuffle 
mappings thereby complicating the solver and the parts of solution application. 
 Really, the only place this has a valid use is in the error handling path 
where we can use the tuple shuffle to emit a fixit that properly reorders 
arguments - something we should be doing even today 
.  Tuple shuffles are also allowed to 
reorder around variadic arguments which makes matching that much more difficult.
- SIL: Has to account for tuple shuffles in multiple places.  One notable one 
is that SILGen has to support two different paths when lowering tuple shuffles 
- one for variadic shuffles and the other for “normal” shuffles.  Each path 
supports a different subset of the features necessary to implement the full 
feature that is tuple shuffles, neither can really be simplified down to a 
common core in their current iteration.

If you want some numbers, I spent the evening removing them from the codebase 
and came up with a win of about 1500 LoC.  Each line of code supporting a 
feature that people aren’t actually using.

~Robert Widmann


> On May 4, 2017, at 10:35 PM, Tony Arnold via swift-evolution 
>  wrote:
> 
> 
>> On 5 May 2017, at 12:27, Félix Cloutier via swift-evolution 
>>  wrote:
>> 
>> Why?
> 
> Not trying to be smart, but the reasoning is in Robert’s proposal:
> 
>>> Their inclusion in the language complicates every part of the compiler 
>>> stack, uses a syntax that can be confused for type annotations 
>>> (https://twitter.com/CodaFi_/status/860246169854894081), contradicts the 
>>> goals of earlier SE's (see SE-0060), and makes non-sensical patterns 
>>> possible in surprising places.
> 
> 
> Robert, maybe you could include some detail about how this feature is 
> complicating the compiler stack, and what will be improved by it’s removal?
> 
> 
> 
> That being said, I’m all for you guys making your lives easier at the cost of 
> something we shouldn’t be using in the first place…
> 
> 
> Tony
> 
> 
> --
> Tony Arnold
> +61 411 268 532
> http://thecocoabots.com/
> 
> ABN: 14831833541
> 
> ___
> 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] [Proposal][Discussion] Deprecate Tuple Shuffles

2017-05-04 Thread Robert Widmann via swift-evolution
Hi all,

So sorry that this proposal comes so late in the game, but I feel it’s too 
important not to bring it to the attention of the community now.  Attached is a 
proposal to deprecate a language feature many of you will probably have never 
had the chance to use: Tuple Shuffles.  I’ve attached a copy of the first draft 
of the proposal below, but the latest copy can be read on Github 
.

Thanks!

~Robert Widmann

Deprecate Tuple Shuffles

Proposal: SE- 

Authors: Robert Widmann 
Review Manager: TBD
Status: Awaiting review
 
Introduction

This proposal seeks the deprecation of a little-known feature of Swift called a 
"Tuple Shuffle".

 
Motivation

A tuple-shuffle is an undocumented feature of Swift in which one can re-order 
the indices of a tuple by writing a pattern that describes a permutation in a 
syntax reminiscent of adding type-annotations to a parameter list:

let a = (x: 1, y: 2)
var b: (y: Int, x: Int)
b = a
It can be used to simultaneously destructure and reorder a tuple:

let tuple = (first: 0, second: (x: 1, y: 2))
let (second: (x: b, y: c), first: a) = tuple
It can also be used to map parameter labels out of order in a call expression:

func foo(_ : (x : Int, y : Int)) {}
foo((y: 5, x: 10)) // Valid
Note that a tuple shuffle is distinct from a re-assignment through a tuple 
pattern. For example, this series of statements will continue to function as 
before:

var x = 5
var y = 10
var z = 15
(z, y, x) = (x, z, y)
Their inclusion in the language complicates every part of the compiler stack, 
uses a syntax that can be confused for type annotations 
, contradicts the goals 
of earlier SE's (see SE-0060 
),
 and makes non-sensical patterns possible in surprising places.

Take switch-statements, for example:

switch ((0, 0), 0){ 
case (_ : let (y, z), _ : let s): () // We are forbidden from giving these 
patterns names other than "_" 
default: () 
}
This proposal seeks to deprecate them in Swift 3 compatibility mode and enforce 
that deprecation as a hard error in Swift 4 to facilitate their eventual 
removal from the language.

 
Proposed
 solution

Construction of Tuple Shuffle Expressions will become a warning in Swift 3 
compatibility mode and will be a hard-error in Swift 4.

 
Detailed
 design

In addition to the necessary diagnostics, the grammar will be ammended to 
simplify the following productions:

tuple-pattern → (tuple-pattern-element-list )
tuple-pattern-element-list → tuple-pattern-element | tuple-pattern-element , 
tuple-pattern-element-list
- tuple-pattern-element → pattern | identifier:pattern
+ tuple-pattern-element → pattern
 
Impact
 on Existing Code

Because very little code is intentionally using Tuple Shuffles, impact on 
existing code will be negligible but not non-zero.

 
Alternatives
 considered

Continue to keep the architecture in place to facilitate this feature.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Revamp Optional and Throws

2017-04-30 Thread Robert Widmann via swift-evolution

> On Apr 30, 2017, at 1:43 PM, Gor Gyolchanyan  wrote:
> 
> It doesn’t have to be a massive source-break, since this pitch is supposed to 
> be a strict superset of what Optional and throwing is currently.
> The only thing that I can think of at this moment that would break is this 
> syntax:
> 
> let foo: Int? = .none // Error: Can’t convert (Error) -> Int? to Int?
> 

Except it’s not a strict superset if you break every use of this case as an 
RValue.  Especially when so much of Swift’s syntax and major patterns revolve 
around the manipulation of optionals.

> The ExpressibleByNilLiteral, the try/throw syntax, all of those things would 
> work as they are right now.
> Error handling as it is currently, is essentially a hidden `error` out 
> parameter and a whole bunch of codegen.
> Even the semantical changes described earlier would be purely additive.

Don’t get me wrong, I think you’ve identified the problem space well, I just 
disagree with the solution.

~Robert Widmann

> 
>> On Apr 30, 2017, at 8:35 PM, Robert Widmann  wrote:
>> 
>> This "revamp" is isomorphic to adding a Sum type to stdlib and plumbing 
>> error handling syntax through.  I'd much rather see that than the massive 
>> source-break this would entail.
>> 
>> ~Robert Widmann
>> 
>> 2017/04/30 13:11、Gor Gyolchanyan via swift-evolution 
>>  のメッセージ:
>> 
>>> I’d like to suggest a bit of redesigning the Optional type and throwing 
>>> functions to provide a single powerful and flexible mechanism for dealing 
>>> with unexpected situations.
>>> 
>>> In short, The Optional would have an associated value of type Error added 
>>> to its `none` case, which would describe the reason why the wrapped value 
>>> is missing.
>>> 
>>> public enum Optional {
>>> 
>>>  case .some(Wrapped)
>>> 
>>>  case .none(Error)
>>> 
>>> }
>>> 
>>> The Optional's ExpressibleByNilLiteral would initialize it with an error 
>>> that corresponds to what is currently fatalError-ed as "unexpectedly found 
>>> nil while unwrapping an Optional value".
>>> 
>>> The forced unwrapping operator (postfix `!`) would behave the same way as 
>>> it does now, except in case of a fatal error it would print out the 
>>> underlying error, instead of the aforementioned hard-coded string.
>>> 
>>> The optional chaining operator (postfix `?`) would behave the same way as 
>>> it does now, except when it stops evaluating and returns the Optional, it 
>>> would contain the error, returned by the sub-expression that failed to 
>>> evaluate.
>>> 
>>> Any throwing function would be equivalent to a function that returns an 
>>> Optional. If the function is declared as throwing and returning an Optional 
>>> at the same time, it would be equivalent to a function returning an 
>>> Optional Optional.
>>> 
>>> The if-let statement would bind the `let` variable to the wrapped value 
>>> inside the "then" block and would bind it to the error in the "else" block. 
>>> Chained else-if blocks would all be considered part of the overarching 
>>> "else" block, so all of them would be able to access the error bound to the 
>>> if-let name.
>>> 
>>> The guard-let and case-let statements are essentially just rewrites of 
>>> if-let with some added logic.
>>> 
>>> The `try` keyword, applied to an optional would behave like this:
>>> 
>>> public func try(_ optional: T?) throws -> T {
>>>  guard let wrapped = optional else {
>>>  throw wrapped // Remember, if-let, guard-let and case-let statements 
>>> bind the let name to the error in case of a failure.
>>>  }
>>>  return wrapped
>>> }
>>> 
>>> Multiple let bindings in a single if-let statement are essentially rewrites 
>>> of a nested chain of if-let statements.
>>> 
>>> The `try` keyword applied to an optional would unwrap the value or throw 
>>> the error.
>>> The `try?` keyword applied to a throwing function call would cause any 
>>> thrown errors to be caught and put into the returned Optional, instead of 
>>> simply ignored.
>>> The `try!` keyword applied to a throwing function call would behave as 
>>> you'd expect: just like `try?` except immediately force-unwrapped.
>>> 
>>> A throwing function would be convertible to a non-throwing 
>>> optional-returning function and vice versa.
>>> This would allow making use of throwing functions when dealing with 
>>> generics or protocols that allow arbitrary return types, without having to 
>>> sacrifice the convenience of error-handling logic. Conversely, it would 
>>> allow to write generic code that deals with any type of function without 
>>> having to implement special cases for throwing functions. This means that 
>>> the two function types would be interchangeable and one would be able to 
>>> satisfy protocol requirements of the other. The `rethrows` idiom would then 
>>> become a natural consequence of writing generic functions that may return 
>>> optional and non-optional results just as well.
>>> 
>>> 

Re: [swift-evolution] switch must be exhaustive, consider adding a default clause

2017-04-11 Thread Robert Widmann via swift-evolution
What Joe is referring to is the kind of refinement-style rules that would be 
necessary to teach the type checker about how to that kind of analysis.  Right 
now, all our switch analysis, and even this example, are just DI and 
control-flow checks.

> On Apr 11, 2017, at 2:24 PM, Drew Crawford via swift-evolution 
>  wrote:
> 
> 
> 
> 
> On April 11, 2017 at 11:38:05 AM, Joe Groff (jgr...@apple.com 
> ) wrote:
> 
>> By design, Swift avoids making semantic rules based on that kind of 
>> analysis, since it would be brittle and difficult to describe when the 
>> compiler can and can't see that a condition holds nonlocally like this.
> 
> Swift *currently implements* semantic rules based on this kind of analysis.  
> Exhibit A:
> 
> func foo() {
> 
> let a: Bool
> 
> if UUID().uuidString == "non-local condition" {
> 
> a = true
> 
> }
> 
> else {
> 
> preconditionFailure("Don't initialize a")
> 
> }
> 
> print("\(a)") //NOT: error: a is uninitialized
> 
> }
> 
> ___
> 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) Conformance Regions

2017-04-02 Thread Robert Widmann via swift-evolution
Any proposal that seeks to add private conformances needs to answer to the 
dynamic side of Swift, most importantly: What does this return:

let f = Foo()
f is Bar

If the answer is “it depends”, it needs to be explicitly stated where and how.

> On Mar 30, 2017, at 1:07 PM, Ross O'Brien via swift-evolution 
>  wrote:
> 
> This idea was had during the SE-0159 Review regarding removing fileprivate  
> and I'm creating a new discussion thread for its consideration. It's neither 
> in favour of nor against keeping fileprivate, but is intended to address an 
> idiom which has led to some resentment against fileprivate.
> 
> Copy-pasting from my original post on this:
> 
> When we declare a type, we declare properties and functions which that type 
> has.
> When we extend a type, we add functions to the type. (I'm including computed 
> properties in this.)
> It has become an idiom of Swift to declare an extension to a type for each 
> protocol we want it to conform to, for reasons of code organisation and 
> readability. This can be true even if conformance to the protocol was a 
> primary intent of creating the type in the first place.
> 
> The intent of the scoped access level (one use of the current private 
> keyword) is to allow programmers to create properties and functions which are 
> limited to the scope of their declaration. A protocol conformance can be 
> written, with the aid of helper functions, in the confidence that the helper 
> functions are not visible outside the extension, minimising their impact on 
> other components of the module.
> However, some protocol conformances require the type to have a specific 
> property, which the extension cannot facilitate. Some protocol conformances 
> don't require a property, but it would be really useful to have one, and 
> again an extension can't facilitate.
> 
> Example: we want to be able to write this, but we can't:
> 
> private protocol Bar
> {
>   var integer : Int { get }
>   func increment()
> }
> 
> struct Foo
> {
> }
> 
> extension Foo : Bar
> {
>   var integer : Int
> 
>   private var counter : Int
>   func increment()
>   {
> counter += 1
>   }
> }
> 
> This leads to a workaround: that properties are added to the original type, 
> and declared as fileprivate. They're not intended to be visible to any scope 
> other than the conforming extension - not even, really, to the type's 
> original scope.
> 
> Continuing the example: we've compromised and written this:
> 
> struct Foo
> {
>   fileprivate var integer : Int
>   fileprivate var counter : Int
> }
> 
> extension Foo : Bar
> {
>   func increment()
>   {
> counter += 1
>   }
> }
> 
> This is not a fault of fileprivate (though it's a clunky name), or private. 
> Renaming these levels does not solve the problem. Removing private, such that 
> everything becomes fileprivate, does not solve the problem. The problem is in 
> the extension system.
> 
> Proposal:
> Suppose we approached extensions differently.
> 
> Suppose we created a 'conformance region' inside a type declaration - a scope 
> nested within the type declaration scope - and that this conformance region 
> had its own access level. It's inside the type declaration, not separate from 
> it like an extension, so we can declare properties inside it. But literally 
> the only properties and functions declared inside the region but visible 
> anywhere outside of it, would be properties and functions declared in the 
> named protocol being conformed to.
> 
> So, visually it might look like this:
> 
> struct Foo
> {
>   conformance Bar // or conformance Foo : Bar, but since the region is inside 
> Foo that's redundant
>   {
> var integer : Int // visible because Foo : Bar, at Bar's access level
> 
> var counter : Int = 0 // only visible inside the conformance scope, 
> because not declared in Bar
> 
> func increment() // visible because Foo : Bar, at Bar's access level
> {
>   counter += 1
> }
>   }
> }
> 
> I've introduced a new keyword for this example, conformance, though it may be 
> clear enough to keep using extension. As the extension is inside the type 
> there's no need to redeclare the type being extended. From this example, Foo 
> conforms to Bar, in the same file; it's just been written inside Foo's type 
> declaration, and indented one level, instead of after it.
> 
> Aspects worth considering (some already pointed out by others):
> The original idea for this is that the conformance region exists only to 
> allow the type to conform to a protocol (though possibly more than one), and 
> that only properties and functions declared in those protocols would be 
> accessible outside of the region, at whatever access level the protocol(s) 
> originally declared.
> Existing access terms (internal, fileprivate, etc.) could be used to increase 
> the visibility (to a maximum of the visibility of the declared type, e.g. a 
> public property in a conformance region of an 

Re: [swift-evolution] [Draft] Package Manager Custom Targets Layout

2017-03-26 Thread Robert Widmann via swift-evolution
A huge +1 for this proposal (and I’m definitely saying that partially because 
it folds in the test targets proposal).  Having a flexible layout will make 
packages that need to support additional structure for things like alternative 
package managers or more exotic dependency trees a reality.

~Robert Widmann

> On Mar 25, 2017, at 9:20 PM, Karl Wagner via swift-evolution 
>  wrote:
> 
> Hi,
> 
> I like the part of the proposal which stops inferring targets from the 
> directory layout; I’ve always found that stuff pretty annoying.
> 
> Two points:
> 
> 1) I’m not sure about listing all of the test targets together with the 
> product targets. I feel it may be better to have them as separate Arrays.
> 
> 2) I think we need a way to specify directories non-recursively. For example:
> 
> - Sources
> | - Foo
> | | - MultipleImplementations
> | | | - Impl1
> | | | - Impl2
> 
> In this case, “MultipleImplementations” contains some common definitions, but 
> has multiple potential implementations. Impl1 and Impl2 will each implement 
> the functionality in their own way, perhaps making use of platform-specific 
> features or optional dependencies. Basically, I want to import 
> “MultipleImplementations” non-recursively, then decide which 
> subdirectory/implementation to use based on some build condition:
> 
> .Target(“Foo”, sources: [“Sources/Foo”, 
> “[NR]Sources/Foo/MultipleImplementations”])
> 
> if someCondition {
>   
> package.targets[0].sources.append(“Sources/Foo/MultipleImplementations/Impl1”)
> else {
>   
> package.targets[0].sources.append(“Sources/Foo/MultipleImplementations/Impl2”)
> }
> 
> The workaround today is to test for the inverse and add every other directory 
> to “exclude”, but that’s not an elegant long-term solution.
> 
> - Karl
> 
>> On 24 Mar 2017, at 21:26, Ankit Aggarwal via swift-evolution 
>> > wrote:
>> 
>> Hi,
>> 
>> We would love to get some feedback on a draft proposal for defining custom 
>> target layouts in the Package Manager. This proposal allows overriding the 
>> target layout rules set by the Package Manager and simplifies some complex 
>> "magic" behaviours. 
>> 
>> You can find the proposal at the link below. The text is also included in 
>> the email.
>> 
>> https://github.com/aciidb0mb3r/swift-evolution/blob/custom-targets-layout/proposals/-package-manager-custom-targets-layout.md
>>  
>> 
>> 
>> Thanks,
>> Ankit
>> 
>> --
>> 
>> Package Manager Custom Targets Layout
>> Proposal: SE- 
>> 
>> Author: Ankit Aggarwal 
>> Review Manager: TBD
>> Status: Discussion
>> Bug: SR-29 
>> Introduction
>> This proposal enhances the Package.swift manifest APIs to support custom 
>> target layouts, and removes a convention which allowed omission of targets 
>> from the manifest.
>> 
>> Motivation
>> The Package Manager uses a convention system to infer targets structure from 
>> disk layout. This works well for most packages, which can easily adopt the 
>> conventions, and frees users from needing to update their Package.swift file 
>> every time they add or remove sources. Adopting the conventions is more 
>> difficult for some packages, however – especially existing C libraries or 
>> large projects, which would be difficult to reorganize. We intend to give 
>> users a way to make such projects into packages without needing to conform 
>> to our conventions.
>> 
>> The current convention rules make it very convenient to add new targets and 
>> source files by inferring them automatically from disk, but they also can be 
>> confusing, overly-implicit, and difficult to debug; for example, if the user 
>> does not follow the conventions correctly which determine their targets, 
>> they may wind up with targets they don't expect, or not having targets they 
>> did expect, and either way their clients can't easily see which targets are 
>> available by looking at the Package.swift manifest. We want to retain 
>> convenience where it really matters, such as easy addition of new source 
>> files, but require explicit declarations where being explicit adds 
>> significant value. We also want to make sure that the implicit conventions 
>> we keep are straightforward and easy to remember.
>> 
>> Proposed solution
>> We propose to stop inferring targets from disk. They must be explicitly 
>> declared in the manifest file. The inference was not very useful, as targets 
>> eventually need to be declared in order to use common features such as 
>> product and target dependencies, or build settings (which are planned for 
>> Swift 4). Explicit target declarations make a package easier to understand 
>> by clients, and allow us to provide good diagnostics when the layout on disk 
>> does not match 

Re: [swift-evolution] [Proposal] [Discussion] Explicit Toll-Free Conversions

2017-03-22 Thread Robert Widmann via swift-evolution
Correct.  This section is referring more to the NS-side of things.

> On Mar 23, 2017, at 1:38 AM, Slava Pestov <spes...@apple.com> wrote:
> 
> 
>> On Mar 22, 2017, at 10:35 PM, Robert Widmann via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> This introduces a source-breaking change that affects consumers of APIs that 
>> are explicitly taking or vending instances of bridged CF or Objective-C 
>> types. However, recent importer advances have made APIs like this far less 
>> numerous. In practice, we expect the source breakage to eludicate places 
>> where implicit conversions were accidentally being performed behind the 
>> user's back.
>> 
> 
> I thought CF APIs were still imported as taking and returning CFArray, etc, 
> without automatic bridging to Swift collections. Is this no longer the case?
> 
> Slava
> 

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


[swift-evolution] [Proposal] [Discussion] Explicit Toll-Free Conversions

2017-03-22 Thread Robert Widmann via swift-evolution
Good evening all,

Attached is the proposal text that came out of a short discussion on Twitter 
 about squashing one 
more case of implicit conversions in the language.  This proposal seeks to 
remove the implicit nature of toll-free bridging in favor of an explicit 
as-cast.  The proposal can also be read as a gist 
, and the most 
up-to-date copy may be found on swift-evolution itself 
.

Cheers,

~Robert Widmann

Explicit Toll-Free Conversions

Proposal: SE- 
Authors: Robert Widmann 
Review Manager: TBD
Status: Awaiting review
 
Introduction

To continue removing further implicit conversions from the language, implicit 
toll-free bridging should be deprecated in Swift 3 and removed in Swift 4.0.

 
Motivation

Swift currently allows implicit conversions between CF types and their 
toll-free-bridged Objective-C counterparts. This was meant to maintain parity 
with the feature in Objective-C. However, the presence of implicit conversions 
is no longer in-line with the expectations of Swift's type system. In addition, 
advancements in the Clang importer have made interaction with imported CF and 
Foundation types nearly seamless - obviating the need for this feature in 
general. For the sake of safety, and in the spirit of continuing the work of 
SE-0072 

 and facilitating SE-0083 
,
 we propose the deprecation and removal of this implicit conversion in favor of 
an explicit as cast.

 
Proposed
 solution

The implicit conversion between toll-free-bridged types shall be removed. In 
its place, the user should use explicit ascasts to convert bewteen bridged CF 
and Objective-C types.

 
Detailed
 Design

When in Swift 3 mode, the compiler shall warn when it encounters the need to 
perform an implicit conversion. At the warning site, it can offer the explicit 
as cast to the user as a fix-it.

func nsToCF(_ ns: NSString) -> CFString {  
  return ns // warning: 'NSString' is not implicitly convertible to 'CFString'; 
did you mean to use 'as' to explicitly convert?
}

func cfToNS(_ cf: CFString) -> NSString { 
  return cf // warning: 'CFString' is not implicitly convertible to 'NSString'; 
did you mean to use 'as' to explicitly convert?
}
When in Swift 4 mode, the compiler shall no longer perform the implicit 
conversion and relying on this behavior will be a hard error.

func nsToCF(_ ns: NSString) -> CFString {  
  return ns // error: cannot convert return expression of type 'NSString' to 
return type 'CFString'
}

func cfToNS(_ cf: CFString) -> NSString { 
  return cf // error: cannot convert return expression of type 'CFString' to 
return type 'NSString'
}
 
Source
 compatibility

This introduces a source-breaking change that affects consumers of APIs that 
are explicitly taking or vending instances of bridged CF or Objective-C types. 
However, recent importer advances have made APIs like this far less numerous. 
In practice, we expect the source breakage to eludicate places where implicit 
conversions were accidentally being performed behind the user's back.

 
Effect
 on ABI stability

This proposal has no effect on the Swift ABI.

 
Effect
 on API resilience

This proposal has no effect on API resilience.

 
Alternatives
 considered

Do nothing and continue to accept this implicit conversion.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Property Selectors

2017-03-14 Thread Robert Widmann via swift-evolution
Lenses !  My only concern is that arbitrary 
effects can be attached to setters and getters, which can lead to surprising 
results when using the property reference.  As a language feature, I’d be 
interested to see where discussion around this will lead.

~Robert Widmann

> On Mar 14, 2017, at 4:02 AM, Andrew Thompson via swift-evolution 
>  wrote:
> 
> Hello Swift Evolution Community,
> 
> I’ve been thinking about a new language feature that would allow properties 
> to be first class citizens. The basic idea is as follows:
> 
>   let x: PropertySelector = 
> #property(UIView.frame.origin.x)
>   let view: UIView = …
>   view.frame.origin.x = 20
>   x.read(view) // returns 20
>   x.write(view, value: 9091)
>   view.frame.origin.x // now 9091
> 
> This is a trivial example, but now we can do more interesting things in our 
> code. For example, we can animate any property on a view (that is documented 
> to be animatable of course):
> 
>   func animate(view: UIView, property: PropertySelector, 
> amount: Int) {
>   let originalValue = property.read(view)
>   func generateKeyFrames() {
>   let step = 1.0 / Double(amount)
>   for i in 0..   let newValue = originalValue + CGFloat(i)
>   let time = Double(i) / Double(amount)
>   UIView.addKeyframe(withRelativeStartTime: time,
> 
> relativeDuration: step,
> animations: { 
> property.write(view, value: newValue) }
>   )
>   }
>   }
>   
>   UIView.animateKeyframes(withDuration: 1.0,
>  delay: 0,
>  options: [],
>  animations: 
> generateKeyFrames,
>  completion: nil)
>   }
> 
>   let myView: UIView = …
>   myView.frame = CGRect(x: 20, y: 100, width: 99, height: 120)
> 
>   // once this completes, myView.frame.origin.x == 120
>   animate(view: myView, property: #property(UIView.frame.origin.x), 
> amount: 100)
>   
>   // once this completes, myView.frame.size.width == 198
>   animate(view: myView, property: #property(UIView.frame.size.width), 
> amount: 99)
> 
> I think this would be a pretty neat feature to have, what do you think?
> 
> Cheers,
> - Andrew
> ___
> 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] List all values of a simple enum and extension constraint to enum types

2017-03-13 Thread Robert Widmann via swift-evolution
This feature keeps being brought up.  SR-3050 
 and rdar://problem/28952398 
 are tracking it, as well as this Evolution proposal 
by Jacob .  The 
implementation has been discussed multiple times on social media (one example 
that comes to mind ).  
At this point it’s just a matter of sitting down to flesh out the 
implementation and seeing its consequences on Swift code, which we now have 
ample time to do because this feature is not in scope for Swift 4.

~Robert Widmann

> On Mar 10, 2017, at 1:15 PM, Trevör ANNE DENISE via swift-evolution 
>  wrote:
> 
> Hello everyone,
> 
> As I was writing a program, I realised that I could make it safer by being 
> able to list all possible cases of a Swift enum.
> This is similar to what has been described there:
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151207/001233.html
>  
> 
> 
> Is there any updates about it since 2015?
> 
> Also, do you think this would be a good idea to make extensions constrainable 
> by enum types, like that?
> extension Type where P1: enum {
> }
> 
> You could then write something similar to this:
> 
> protocol A {
> associatedtype P1
> associatedtype P2
> static var p1PossibleValues:[P1] { get }
> static var p2PossibleValues:[P2] { get }
> }
> 
> extension A where P1: enum, P2: enum {
>   static var p1PossibleValues:[P1] { return p1PossibleValues.allValues }
>   static var p2PossibleValues:[P2] { return p2PossibleValues.allValues }
> }
> 
> Would it make sense to do it this way?
> 
> 
> 
> Trevör
> ___
> 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] Infer types of default function parameters

2017-03-11 Thread Robert Widmann via swift-evolution
You may be missing/misspelling the typealias declaration.  This has been in 
Policy.swift for a while now, and I can reproduce this as far back as 2.2 in 
the Bluemix sandbox.

~Robert Widmann

> On Mar 11, 2017, at 7:41 PM, Jaden Geller via swift-evolution 
>  wrote:
> 
> 
>> On Mar 11, 2017, at 3:22 PM, Ben Cohen > > wrote:
>> 
>>> 
>>> On Mar 11, 2017, at 1:17 PM, Jaden Geller via swift-evolution 
>>> > wrote:
>>> 
>>> 
>>> 
>>> On Mar 11, 2017, at 12:20 PM, David Sweeris via swift-evolution 
>>> > wrote:
>>> 
 
> On Mar 11, 2017, at 12:57 AM, Jean-Daniel via swift-evolution 
> > wrote:
> 
> -1
> 
> It would be inconsistent to allow it for deterministic literals (String) 
> and not for non deterministic literal (int which can be either a Int, 
> Uint, Float, …)
 
 If I’m not mistaken, even with `bar = “baz”`, `String` is merely the 
 default inferred type. It could be anything that conforms to 
 `ExpressibleByStringLiteral`, right? In that regard, this is kinda just a 
 way to make a function implicitly generic:
 func foo(bar = "baz") {…}
 becomes:
 func foo(bar: T = "baz") {…}
 
>>> 
>>> As I understood it, omitting the type would work identically to `let` 
>>> declarations. A string literal without a type defaults to `String`. 
>>> Treating it as a generic function is a bad idea IMO.
>>> 
>> 
>> More specifically, a string literal without a type defaults to the 
>> StringLiteralType typealias:
>> 
>> typealias StringLiteralType = StaticString
>> let s = "abc"
>> print(type(of: s))
>> // prints StaticString
> 
> What version of the Swift compiler are you using? I don’t observe this 
> behavior. That code prints `String` for me.
> 
>> 
>>> I don't think this sugar is worth any amount of added complexity. Most 
>>> function arguments will have not have default values and this have to 
>>> continue to declare the type, so this would only be more concise in very 
>>> few cases. I'd prefer the consistency of always having to explicitly 
>>> declare the argument type at a function boundary.
>>> 
>>> To call a function, you need to know what type to pass in. This becomes 
>>> more difficult when not make explicit, particularly when a more complicated 
>>> expression is used as a default. -1
>>> 
 Is there anything we can do with a variable, if all we know of it is that 
 it conforms to `ExpressibleByStringLiteral`? I can’t think of anything… If 
 we had a way to get back the literal string which the variable was 
 initialized with, we could initialize other values with that, but the 
 protocol doesn’t require us to store it. Come to think of it, is there 
 even a way to store a literal value in its “untyped” form? You can declare 
 a variable to of type `IntegerLiteralType`, but the type system then 
 treats it as an `Int`.
 
 So while it looks nice (to me, anyway) I’m not sure you could actually do 
 anything with it. Or am I looking at this wrong?
 
 - Dave Sweeris
 ___
 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

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


Re: [swift-evolution] [Draft] Really Simple Submodules

2017-03-06 Thread Robert Widmann via swift-evolution

> On Mar 6, 2017, at 10:22 AM, Michel Fortin  wrote:
> 
> I believe `submodule` in my proposal introduces a segmented-scope-like thing, 
> akin to how the various files included in a module are combined as one 
> collection of declarations. And you have the ability to import things from 
> that scope with `import submodule`, like with modules. I think the name 
> submodule fits as some sort of "lesser module", but if someone has a better 
> name for this I'll listen.
> 

My beef is not with that, my beef is with the idea that `public` should leak 
APIs across module boundaries by default and that a module is merely a way to 
section off internal declarations.  Matthew has given these a name in his 
scoped access proposal, and Swift today gives the kind of scope you’re trying 
to define a name - it’s called fileprivate.

> We could add a submodule-private access level, but I'm not sure it is worth 
> its weight. There's plenty of possibilities, but I know I wouldn't be too 
> happy with more access levels than what we have now. For each access level 
> you add the more fine-grained they become and the more difficult it is to 
> decide which one is the right one. Hence why I'm keeping the idea of adding 
> access levels as a separate concern worth of its own debate. This proposal is 
> solely focused on providing intra-module boundaries, and I think those 
> boundaries can work without introducing a new access level.
> 
>> On 6 mars 2017, at 2:39, Robert Widmann > > wrote:
>> 
>> If this were a problem that could be fixed by tooling, you'd be submitting 
>> this proposal against the package manager.
>> 
>> It's important to note I'm approaching this problem from the principles that 
>> underpin modular programming practices in other languages, it is not merely 
>> "philosophical".  A proposal that claims to support submodules should come 
>> with some consistent support for modularity or rebrand to more honestly 
>> reflect its contents.  As it stands, this proposal effectively introduces 
>> another level of access (while paradoxically claiming to avoid access 
>> control discussions), and suggests more access control to support its 
>> contents later.  Maybe discussion should start there instead of with 
>> "submodules".
>> 
>> ~Robert Widmann
>> 
>> 2017/03/06 0:39、Michel Fortin > > のメッセージ:
>> 
>>> 
 On 5 mars 2017, at 22:28, Robert Widmann > wrote:
 
 This proposal strikes me not as a submodules proposal, but as a sneaky way 
 to add 'friend' to Swift.  It is conceptually simpler because it doesn't 
 address modularity at all!
 
 ~Robert Widmann
 
 2017/03/05 17:16、Michel Fortin via swift-evolution 
 > のメッセージ:
 
> Sorry for introducing yet another submodule proposal out of the blue.
> 
> I'm a bit surprised at how far-reaching the various submodule proposals 
> floated on this list have been. Directories, access controls, @exported 
> imports... For comparison's sake here's one that is *really* simple and 
> short I wrote today. Best of all: it requires no new access modifier. 
> 
> I also expect everyone to scream at it because it does not include all 
> the desirable features of a submodule system. At the very least I'll have 
> redefined the meaning of lightweight in that discussion. Good reading.
> 
> Also available here: 
> https://gist.github.com/michelf/779b1bc26a778051b6231b5639665e18 
> 
> 
> 
> ## Motivation
> 
> The goal of this proposal is to provide lightweight intra-module 
> boundaries so you can avoid exposing every `internal` declaration within 
> a big module to all other files in the module.
 
 I don't think this was a stated goal of anybody because that’s not the 
 primary issue submodules are trying to solve.  Projects with a large 
 amount of internal declarations may be clamoring to be put into multiple 
 (sub)modules, but because the style most have converged on doesn’t usually 
 involve a large amount of free functions, your internal declarations are 
 usually types and as such have members that are already encapsulated.
>>> 
>>> Well maybe that's just a problem specific to me, but that's the goal I'd 
>>> like submodule to solve. If I have four intermingled classes, I'd like to 
>>> restrict the interminglement to those four classes. My current options for 
>>> that are a) to create a separate module, b) to put them all in the same 
>>> file with `fileprivate`, or c) tolerate that the rest of the module will 
>>> see everything all the time with `internal`. I'm choosing (c) at the 
>>> 

Re: [swift-evolution] [Draft] Really Simple Submodules

2017-03-06 Thread Robert Widmann via swift-evolution
My proposal doesn't mention ML, though it may have come up during our 
discussions.

I do remember, however, defining modularity many times though indirectly.  Let 
me be clear: A modular system is one in which substitution is the foremost 
goal.  An API boundary may be specified in the form of a set of types, a set of 
free functions, a set of protocols, whatever, but the implementation of these 
are freely substitutable by a different module implementing its innards 
completely differently but implementing the same interface outwardly.  In fact, 
the formal definition for this in Type Theory is the Principle of Substitution 
extended to support structures.

ML carries this principle to its logical conclusions by allowing programs to be 
structured in terms of interfaces so abstract even the underlying type 
definitions are often hidden from you.  This allows programs to be built with a 
high degree of genericity and by definition a high degree of reusability.  
Swift, obviously, has not agreed that that level of abstraction is useful and 
so we cannot wholesale import ML modules into the language - nor would we want 
to as it immediately runs afoul of the “how Swift-y is this addition” question. 
 However, there are many ML-like and ML-inspired languages that have toed this 
line before.  Assemblies in the Microsoft world, packages in the Java and Go 
worlds, and Ruby and Python offer the weakest adherence to this definition, 
with Rust, Clojure, Erlang rounding out the middle, and OCaml and Agda et al. 
trying to aim closest.  

My proposal was built not on top of these, but on top of the existing 
infrastructure and featureset LLVM modules offer us because I felt they offered 
a reasonable degree of modularity given the system we already have, and have 
been battle-tested.

~Robert Widmann

2017/03/06 8:31、Matthew Johnson <matt...@anandabits.com 
<mailto:matt...@anandabits.com>> のメッセージ:

> 
> 
> Sent from my iPad
> 
> On Mar 6, 2017, at 1:39 AM, Robert Widmann via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
>> If this were a problem that could be fixed by tooling, you'd be submitting 
>> this proposal against the package manager.
>> 
>> It's important to note I'm approaching this problem from the principles that 
>> underpin modular programming practices in other languages, it is not merely 
>> "philosophical".  A proposal that claims to support submodules should come 
>> with some consistent support for modularity or rebrand to more honestly 
>> reflect its contents.  
> 
> Robert, you have said several times that ideas suggested by others are not 
> modular and have referenced other languages in the process.  Yet (as far as I 
> know) you haven't actually defined what you believe "modular" means or 
> referenced other languages that you believe provide modularity in the way you 
> are looking for.  Perhaps it would be useful if you provide or reference a 
> definition and mention some specific languages you believe provide good 
> modularity.  
> 
> I believe your proposal mentions the ML module system as specifically not 
> providing the kind of modularity you are looking for.  That makes sense 
> because Swift's protocols already offer similar features.  But that doesn't 
> offer much insight into what you specifically mean by modularity or what 
> other languages inspired that understanding.
> 
> I hope you are willing to elaborate further on this.
> 
>> As it stands, this proposal effectively introduces another level of access 
>> (while paradoxically claiming to avoid access control discussions), and 
>> suggests more access control to support its contents later.  Maybe 
>> discussion should start there instead of with "submodules".
>> 
>> ~Robert Widmann
>> 
>> 2017/03/06 0:39、Michel Fortin <michel.for...@michelf.ca 
>> <mailto:michel.for...@michelf.ca>> のメッセージ:
>> 
>>> 
>>>> On 5 mars 2017, at 22:28, Robert Widmann <devteam.cod...@gmail.com 
>>>> <mailto:devteam.cod...@gmail.com>> wrote:
>>>> 
>>>> This proposal strikes me not as a submodules proposal, but as a sneaky way 
>>>> to add 'friend' to Swift.  It is conceptually simpler because it doesn't 
>>>> address modularity at all!
>>>> 
>>>> ~Robert Widmann
>>>> 
>>>> 2017/03/05 17:16、Michel Fortin via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> のメッセージ:
>>>> 
>>>>> Sorry for introducing yet another submodule proposal out of the blue.
>>>>> 
>>>>> I'm a bit surprised at how far-reaching the vari

Re: [swift-evolution] A Modest (multi-module) Proposal

2017-03-05 Thread Robert Widmann via swift-evolution
What seems most suspect to me is the relation of a Swift module to a build 
target.  Do you mean we literally mate the concepts and provide IDE support, or 
is that more of a conceptual point?

I think the package manager's eventual goal of supporting multi-product 
packages covers most of what you want here (besides, maybe, the performance 
problems with dynamic linking).

~Robert Widmann

2017/03/05 22:55、David Waite via swift-evolution  
のメッセージ:

> Apologies on creating yet another modulary thread in parallel, but I don’t 
> believe I have seen the approach I’ve been mulling over considered. I have 
> been contemplating submodules not from an access scoping perspective, but 
> from a packaging one. In other words rather than defining the ability to have 
> a module contain modules, have multiple peer-level modules contained a 
> library or executable. A module would effectively be a build target, and 
> applications/libraries are composed of modules.
> 
> I’m not yet proposing any other features which would make this work 
> conceptually differently than having one library per module today - I want to 
> see if there is positive feedback around this first. 
> 
> This approach has several advantages that I can think of:
> 1. Relatively simple model to explain
> 2. Additive proposal - if someone wishes to continue to make a framework or 
> app with just a single module, the tools can work the same way they do today
> 3. Still encourages smaller modules, while today this would cause an 
> explosion of included libraries
> 4. Smaller modules provide a tighter level of encapsulation, alleviating some 
> of the pressure for access control levels between module-internal and private
> 5. Resolves existing startup performance issues of dynamic linking large 
> numbers of libraries by allowing modules to be combined into fewer libraries.
> 6. Since modules are defined as build targets:
>6.1 it is possible to model a filesystem-based grouping for modules using 
> build tools
>6.2 source in a module does not need any changes such as annotation to 
> indicate which module it is part of
>6.3 support isn’t modeled by the visual layout of an IDE, can be 
> represented in a multi-target swift package manager file (SE-0146)
> 
> This approach also has two identified disadvantages in its current, 
> simplistic form:
> 1. no inter-module access control yet proposed. This requires extra 
> consideration with modules as a packaging concept, since modules would need 
> to be bundled into the same binary unit
> 2. modules cannot have cyclic type dependencies (same as libraries today). My 
> personal experience is that this leads to better code design and 
> maintainability, but it can be more difficult when designing modules, or 
> refactoring one module into many. 
> 3. as an extension of the above, the extra constraints on making code into a 
> module would limit the ability to use modules as a grouping/naming system for 
> exposed API - dependencies would need to be structured for such a thing to 
> work, which might require code changes
> 4. some submodule proposals may have allowed for a hierarchy of module names, 
> e.g. Foundation and Foundation.Net. There is nothing yet in this proposal 
> which would define how such a system would work.
> 5. I do not have enough knowledge of the functioning of the Swift compiler 
> and build tools to know the impact of this approach.
> 6. Technically this does not preclude submodules as well, although I would 
> suspect having both concepts would mean too much complexity.
> 
> Comments?
> 
> -DW
> ___
> 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] [Draft] Really Simple Submodules

2017-03-05 Thread Robert Widmann via swift-evolution
If this were a problem that could be fixed by tooling, you'd be submitting this 
proposal against the package manager.

It's important to note I'm approaching this problem from the principles that 
underpin modular programming practices in other languages, it is not merely 
"philosophical".  A proposal that claims to support submodules should come with 
some consistent support for modularity or rebrand to more honestly reflect its 
contents.  As it stands, this proposal effectively introduces another level of 
access (while paradoxically claiming to avoid access control discussions), and 
suggests more access control to support its contents later.  Maybe discussion 
should start there instead of with "submodules".

~Robert Widmann

2017/03/06 0:39、Michel Fortin  のメッセージ:

> 
>> On 5 mars 2017, at 22:28, Robert Widmann  wrote:
>> 
>> This proposal strikes me not as a submodules proposal, but as a sneaky way 
>> to add 'friend' to Swift.  It is conceptually simpler because it doesn't 
>> address modularity at all!
>> 
>> ~Robert Widmann
>> 
>> 2017/03/05 17:16、Michel Fortin via swift-evolution 
>>  のメッセージ:
>> 
>>> Sorry for introducing yet another submodule proposal out of the blue.
>>> 
>>> I'm a bit surprised at how far-reaching the various submodule proposals 
>>> floated on this list have been. Directories, access controls, @exported 
>>> imports... For comparison's sake here's one that is *really* simple and 
>>> short I wrote today. Best of all: it requires no new access modifier. 
>>> 
>>> I also expect everyone to scream at it because it does not include all the 
>>> desirable features of a submodule system. At the very least I'll have 
>>> redefined the meaning of lightweight in that discussion. Good reading.
>>> 
>>> Also available here: 
>>> https://gist.github.com/michelf/779b1bc26a778051b6231b5639665e18
>>> 
>>> 
>>> ## Motivation
>>> 
>>> The goal of this proposal is to provide lightweight intra-module boundaries 
>>> so you can avoid exposing every `internal` declaration within a big module 
>>> to all other files in the module.
>> 
>> I don't think this was a stated goal of anybody because that’s not the 
>> primary issue submodules are trying to solve.  Projects with a large amount 
>> of internal declarations may be clamoring to be put into multiple 
>> (sub)modules, but because the style most have converged on doesn’t usually 
>> involve a large amount of free functions, your internal declarations are 
>> usually types and as such have members that are already encapsulated.
> 
> Well maybe that's just a problem specific to me, but that's the goal I'd like 
> submodule to solve. If I have four intermingled classes, I'd like to restrict 
> the interminglement to those four classes. My current options for that are a) 
> to create a separate module, b) to put them all in the same file with 
> `fileprivate`, or c) tolerate that the rest of the module will see everything 
> all the time with `internal`. I'm choosing (c) at the present time because 
> (a) is too much work and (b) is more messy.
> 
> You are absolutely right in your observation that it's some sort of "friend". 
> But then the same observation could apply to the `internal` members in a 
> module or the `fileprivate` members in a file. The delimiting boundaries are 
> different, but the concept is the same. What I want is the ability to better 
> define those boundaries.
> 
>>> Not a goal: addressing the file-level access fileprivate/private or 
>>> scoped/protected debates. This is left to other proposals.
>>> 
>>> 
>>> ## Summary
>>> 
>>> This proposal adds the declarations `submodule` and `import submodule`. It 
>>> also limits the visibility of `internal` to files with a matching 
>>> `submodule` or `import submodule` declaration.
>>> 
>>> Submodules are never exposed outside of the module. They only change the 
>>> visibility of internal declarations, so there is no point in exposing them 
>>> publicly.
>>> 
>>> Submodules are not bound to directories, nor are they necessarily 
>>> hierarchical.
>>> 
>>> This change is purely additive and introduces no source compatibility issue.
>> 
>> This particular set of changes is, but the `import submodule` change is 
>> source-breaking in that we already have syntax for this.
> 
> Good catch. If you have a module called "submodule" and you import it, 
> that'll break.
> 
>>> 
>>> 
>>> ## Details
>>> 
>>> A `submodule ` declaration at the beginning of a file contains an 
>>> identifier with the submodule name:
>>> 
>>>  submodule Foo
>>> 
>>>  internal func foo() {}
>>>  public func pub() {}
>>> 
>>> `internal` declarations within that file are only visible to other files 
>>> sharing the same submodule name. The submodule only protects `internal` 
>>> declarations: `public` declarations in the file are visible everywhere (in 
>>> other submodules and in other modules).
>>> 
>> 
>> This definition of public is 

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-03-05 Thread Robert Widmann via swift-evolution
A lot of “Swift Style” is “LLVM Style” enforced in little corners of the 
language (I, too, like to keep my cases indented a bit further).  There are 
formatting tools available to make your Swift look C#-ish if you want :)

> On Mar 5, 2017, at 7:21 AM, Joanna Carter via swift-evolution 
>  wrote:
> 
>> It's part of what has become Swift style and I'm quite happy about it. 
>> Indent on case and on case content is too much indenting :)
>> 
>>> On 3 Mar 2017, at 11:06, Karl Wagner via swift-evolution 
>>>  wrote:
>>> 
>>> 
 On 3 Mar 2017, at 05:52, T.J. Usiyan via swift-evolution 
  wrote:
 
 I would rather that we use the (not-entirely-pleasant-to-me) "curly brace 
 without an indent" used for switches+cases.  
>>> 
>>> Is that actually “how we do things in Swift”? I always thought it was just 
>>> Xcode being silly…
>>> 
>>> I should probably file a radar about it in either case.
> 
> I have to say, I really *hate* "Swift style". It wouldn't be so bad if I 
> could change the indentation rules in Xcode.
> 
> For over 25 years, I have written code with curly braces always on their own 
> line, opening ones aligned with the start of the preceding line.
> 
> As for switch..case statement indenting, the default supplied by code 
> completion is laid ou thus :
> 
>switch value {
>case pattern:
>  code
>default:
>  code
>}
> 
> Whereas, for Objective-C, code completion gives us :
> 
>switch (value) {
>  case pattern:
>code
>break;
> 
>  default:
>break;
>}
> 
> With Objective-C, all I had to do was move the opening curly brace to the 
> next line and Xcode would keep the same indentation :
> 
>switch (value)
>{
>  case pattern:
>code
>break;
> 
>  default:
>break;
>}
> 
> Now, in Swift, not only do I not have the ability to group lines of code 
> together with braces (interpreted as a closure), if I move the opening brace 
> to the next line and indent the cases (for clarity) :
> 
>switch value
>{
>  case pattern:
>code
>  default:
>code
>}
> 
> … although the opening brace stays put, as soon as I reformat a block of code 
> that includes the switch, I automatically lose the indentation of my cases!
> 
> And, no matter what I do in Xcode preferences, I don't seem to be able to 
> achieve *my* coding standards for Swift.
> 
> There are days when I feel like reverting to Objective-C
> 
> --
> Joanna Carter
> Carter Consulting
> 
> ___
> 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] [Draft] Really Simple Submodules

2017-03-05 Thread Robert Widmann via swift-evolution
This proposal strikes me not as a submodules proposal, but as a sneaky way to 
add 'friend' to Swift.  It is conceptually simpler because it doesn't address 
modularity at all!

~Robert Widmann

2017/03/05 17:16、Michel Fortin via swift-evolution  
のメッセージ:

> Sorry for introducing yet another submodule proposal out of the blue.
> 
> I'm a bit surprised at how far-reaching the various submodule proposals 
> floated on this list have been. Directories, access controls, @exported 
> imports... For comparison's sake here's one that is *really* simple and short 
> I wrote today. Best of all: it requires no new access modifier. 
> 
> I also expect everyone to scream at it because it does not include all the 
> desirable features of a submodule system. At the very least I'll have 
> redefined the meaning of lightweight in that discussion. Good reading.
> 
> Also available here: 
> https://gist.github.com/michelf/779b1bc26a778051b6231b5639665e18
> 
> 
> ## Motivation
> 
> The goal of this proposal is to provide lightweight intra-module boundaries 
> so you can avoid exposing every `internal` declaration within a big module to 
> all other files in the module.
> 

I don't think this was a stated goal of anybody because that’s not the primary 
issue submodules are trying to solve.  Projects with a large amount of internal 
declarations may be clamoring to be put into multiple (sub)modules, but because 
the style most have converged on doesn’t usually involve a large amount of free 
functions, your internal declarations are usually types and as such have 
members that are already encapsulated.

> Not a goal: addressing the file-level access fileprivate/private or 
> scoped/protected debates. This is left to other proposals.
> 
> 
> ## Summary
> 
> This proposal adds the declarations `submodule` and `import submodule`. It 
> also limits the visibility of `internal` to files with a matching `submodule` 
> or `import submodule` declaration.
> 
> Submodules are never exposed outside of the module. They only change the 
> visibility of internal declarations, so there is no point in exposing them 
> publicly.
> 
> Submodules are not bound to directories, nor are they necessarily 
> hierarchical.
> 
> This change is purely additive and introduces no source compatibility issue.

This particular set of changes is, but the `import submodule` change is 
source-breaking in that we already have syntax for this.

> 
> 
> ## Details
> 
> A `submodule ` declaration at the beginning of a file contains an 
> identifier with the submodule name:
> 
>   submodule Foo
> 
>   internal func foo() {}
>   public func pub() {}
> 
> `internal` declarations within that file are only visible to other files 
> sharing the same submodule name. The submodule only protects `internal` 
> declarations: `public` declarations in the file are visible everywhere (in 
> other submodules and in other modules).
> 

This definition of public is anti-modular.  It seems as though this style of 
submodule will encourage people to split their definitions across multiple 
files (good) then provide a pile of submodule-membership definitions to 
intertwine them with each other as they need access to each other’s symbols 
(bad).  A module is a self-contained entity by definition.  Dependencies should 
generally be on further child (sub)modules - vertically, not horizontally.

> A file can be part of more than one submodule:
> 
>   submodule Foo
>   submodule Bar
> 
>   internal func achoo() {
>   foo() // available in Foo (from other file)
>   }
> 
> This makes the internal `achoo` function visible within both the `Foo` and 
> `Bar` submodules. Also note that it makes internal members of both submodules 
> `Foo` and `Bar` visible within the file.
> 
> A file can access internal declarations of a submodule without having to 
> expose its own internal functions to the submodule with `import submodule`:
> 
>   submodule Test
>   import submodule Foo
> 
>   internal func test() {
>   foo() // internal, imported from Foo
>   achoo() // internal, imported from Foo
>   pub() // public, so always visible
>   }
> 
> Finally, when a file has no submodule declaration, its internal declarations 
> are visible everywhere in the module and all its submodules:
> 
>   --- Hello.swift ---
>   // no submodule declaration
>   internal func hello() {}
> 
>   --- World.swift ---
>   submodule World
>   internal func test() {
>   hello() // visible!
>   }
> 
> 
> ## Nitpicky Details (Conflicting Declarations)
> 
> Declaring `internal` things that share the same name in two separate 
> submodules is not a conflict:
> 
>   --- Foo1.swift ---
>   submodule Foo1
>   class Foo {} // added to Foo1
> 
>   --- Foo2.swift ---
>   submodule Foo2
>   submodule Foo3
>   class Foo {} // added to Foo2 and Foo3
> 
> (Note: It would be a conflict if one of them was `public`, because `public` 
> declarations are always visible everywhere inside (and outside 

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-03-05 Thread Robert Widmann via swift-evolution


~Robert Widmann

2017/03/03 16:10、Matthew Johnson  のメッセージ:

> 
>> On Mar 2, 2017, at 10:52 PM, T.J. Usiyan  wrote:
>> 
>> Submodules will, I hope, afford us the ability to share meaningfully 
>> arranged API. In an ideal scenario, I could have a module that has all of 
>> the smaller pieces of 'utilities and conveniences' that one builds up  
>> broken into submodules. Importing one of the submodules from its enclosing 
>> module shouldn't bring anything extra along. I don't think that we need to 
>> add nearly as many new concepts as `scope-based submodules` introduces. "ABI 
>> Boundaries", "Name Boundaries", "Scope Boundaries”?
> 
> These boundaries already exist.  All the proposal does is give a name to them.

Some of these boundaries (at least the first) are not meant to be user-visible. 
 Some already exist and are just specializations of lexical scope for some 
reason.

> 
>> What he have is built on LLVM Modules and holds together fairly well on its 
>> own. 
>> Our projects, at present, are a module. ABI doesn't have very much to do 
>> with the 'boundary' of our target. The wording around Module maps make it 
>> clear that submodules have been considered Module Maps 
>> 
>> Export statements are not a useful addition. Access modifiers capture this 
>> well enough via open|public etc. When paired with robust import syntax, we 
>> would have everything that we need. 
> 
> Can you elaborate on what you mean by “robust import syntax”?  The top-level 
> export statement has similar semantics to the `public import` in Robert and 
> Jaden’s proposal.  They even used the word “export” in describing the 
> semantics of `public import`.
> 
> It just uses the name `export` rather than `import` to avoid overloading the 
> semantics of `import` and introduces additional features to avoid coupling 
> the internal structure of a module to the view exposed to users of the module.
> 

What about this constitutes an overload?  Importing a (sub)module and exporting 
a (sub)module may sound disjoint because in common parlance they are opposites. 
 As it relates to programming languages, an export is an iteration upon an 
import, a step up.  Where an import opens a submodule's contents to the 
importer, an export opens a submodule's contents to an importer once removed.  
As such, the term "re-export" is sometimes used to make this clear.  We 
represent such relationships with qualifiers, not new declarations.

>> 
>> The changes to scope and access modifiers in `scope-based submodules` are 
>> dramatic and don't seem to pay for themselves at all.
> 
> This aspect makes the proposal more powerful but is not essential to 
> scope-based submodules.  It has been broken out into an independent proposal 
> which so far has received very positive feedback.

>>  
>> 
>> "Top of the file" declaration to declare a submodule is not at all desirable 
>> to me. I would rather that we use the (not-entirely-pleasant-to-me) "curly 
>> brace without an indent" used for switches+cases.  
> 
> If it’s not entirely pleasant why do you prefer that style?
> 
>> 
>> LLVM modules handle circularity, I think. 
> 
> Do you believe circularity is important?  What use cases do you have for that?

What reasons do you have for disallowing it?  If two (sub)modules depend on 
each other's contents and cannot be cleanly nested into each other, their 
dependency is mutual.  We do not have a preprocessor - our modules are semantic 
rather than syntactic - so there isn't a risk of strange behavior like there is 
in older languages.

> 
>> 
>> The ability to import a single type or a list of specific types is of great 
>> value, in my opinion, especially when paired with renaming (we don't have it 
>> but one can dream, no?) Qualified imports are obviously the tact that I 
>> would like to make this possible. Allow the consumer of the API to get as 
>> specific as they need to when importing. I consider it an unfortunate 
>> concession that `import This.That.TheOther` imports as much as it does but 
>> it is, basically, the only major issue that I have with this proposal and it 
>> can't be helped without breaking compatibility. 
> 
> Selective import is an additive feature that is orthogonal to submodules.  I 
> agree that it would be very nice to have, but it is a separate issue IMO.

No it is not. I agree it is a separate issue, but you cannot acknowledge that 
the current behavior is strange and brush it off.

> 
>> 
>> Overall, it is my opinion that we should solve the submodule and import 
>> problems with changes like those proposed here. Modify very little of the 
>> current syntax and semantics. What we have is fairly close and can actually 
>> be coherent even with the additional burden of exposing submodules.
> 
> It sounds like you don’t view encapsulation as an important feature of 
> submodules.  Is that correct?  If so, why not?  Do you believe we need 
> encapsulation boundaries larger 

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution

> On Feb 22, 2017, at 12:41 AM, Matthew Johnson  wrote:
> 
> 
> 
> Sent from my iPad
> 
> On Feb 21, 2017, at 11:09 PM, Robert Widmann  > wrote:
> 
>> 
>>> On Feb 21, 2017, at 11:59 PM, Matthew Johnson >> > wrote:
>>> 
>>> 
 On Feb 21, 2017, at 10:41 PM, Robert Widmann > wrote:
 
 By API boundaries I mean both the one internal to MyModule.Foo and the one 
 defined by MyModule.  Here “the API boundary” is explicitly about the 
 submodule MyModule.Foo, whose internal state may have been “unsealed” in 
 the top level by the extension, but has not been re-exported.
>>> 
>>> I’m sorry, but I just don’t understand how modules form an API boundary in 
>>> this system.  To me a boundary means something that blocks access.  In this 
>>> system `internal` ranges over the entire module and all submodules.  The 
>>> only boundaries I can see besides the module itself are files and lexical 
>>> scopes (with `fileprivate` and `private`).  
>>> 
>> 
>> A module is a named region that introduces a lexical scope into which 
>> declarations may be nested. The name of the module can be used to access 
>> these member declarations. A module, like other aggregate structures in 
>> Swift, may be extended with new declarations over one or more translation 
>> units (files).
>> 
>> 
>> Your API boundary lives, as it does today, at the edges of each (sub)module 
>> declaration.  APIs that are public or open in a module defines code that is 
>> free to move across this boundary and into the open.  APIs that are internal 
>> are free to have their modules unsealed into other internal modules to 
>> enable modular composition.  APIs that are private and fileprivate do not 
>> participate in the API boundary because they are not eligible for any kind 
>> of export.  
>> 
>> If any of that is unclear, please let me know. 
> 
> Yes, in fact parts are unclear.
> 
> "APIs that are public or open in a module defines code that is free to move 
> across this boundary and into the open"
> 
> This is unclear because you're saying submodules form an API boundary and 
> you're also saying we need to make APIs open or public to allow them to move 
> across this boundary.  But then you say we can unseal it (import or extend, 
> right?) within the module and gain visibility to the internal symbols.  Are 
> you trying to say that it's a soft boundary within the module that can be 
> permeated with an import or by extension?

Of course.  Soft implies more permeability than you are actually afforded, but 
if you want to think of it that way then it may help to put it in context.  

For what it’s worth, the bulk of the discussion around this feature is focused 
on author-side concerns like the behavior of internal modules because access 
control makes a mess of any reasonable semantics. 

> 
> If so, that's not the kind of boundary I think many of us are talking about.  
> We're talking about a hard boundary within the module, but broader than a 
> file.

How then, does one go about accessing declarations contained in these kinds of 
impermeable modules?  You must define points of exposure to be able to use the 
module.  What you’re describing is as though you had can only build hierarchies 
of completely private types and then cherry-pick them one-by-one into the open 
- which, mind you, is not a pattern encouraged by any of the access control 
levels we have today and isn’t supported by any language I’m aware of.

> 
>>>  means that it is trivial to put code anywhere within the module that 
>>> extends the submodule and wraps a symbol in a new name and declares it 
>>> `public`.  
>> 
>> Precisely.  That’s the same pattern that good Swift code, arguably good code 
>> in any language that enables hiding, uses today.
>> 
>>> They can also trivially add a `public import MyModule.Foo` anywhere at the 
>>> top level of their file because every file is forced to include top level 
>>> scope.
>> 
>> Perhaps you misunderstand.  Say the APIs in MyModule.Foo were all of 
>> internal or stricter access: The re-export is a no-op.  You cannot change 
>> the access level of declarations, you can only do the modular thing and wrap 
>> them in a palatable interface for export by a module you want to be 
>> user-facing.  You have to decide to make an API public, just as today you 
>> have to decide to make part of an interface public.  I don’t see how this is 
>> distinct from the goals of this proposal.
> 
> Yes, I understand this.  But submodules aren't visible outside the module by 
> default.  It's possible for a submodule to have public and open symbols 
> without the top level public import anywhere in the program.  

> What I'm saying here is that someone in a distant part of the code base could 
> arbitrarily add it if they 

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution

> On Feb 21, 2017, at 11:59 PM, Matthew Johnson  wrote:
> 
> 
>> On Feb 21, 2017, at 10:41 PM, Robert Widmann > > wrote:
>> 
>> By API boundaries I mean both the one internal to MyModule.Foo and the one 
>> defined by MyModule.  Here “the API boundary” is explicitly about the 
>> submodule MyModule.Foo, whose internal state may have been “unsealed” in the 
>> top level by the extension, but has not been re-exported.
> 
> I’m sorry, but I just don’t understand how modules form an API boundary in 
> this system.  To me a boundary means something that blocks access.  In this 
> system `internal` ranges over the entire module and all submodules.  The only 
> boundaries I can see besides the module itself are files and lexical scopes 
> (with `fileprivate` and `private`).  
> 

A module is a named region that introduces a lexical scope into which 
declarations may be nested. The name of the module can be used to access these 
member declarations. A module, like other aggregate structures in Swift, may be 
extended with new declarations over one or more translation units (files).


Your API boundary lives, as it does today, at the edges of each (sub)module 
declaration.  APIs that are public or open in a module defines code that is 
free to move across this boundary and into the open.  APIs that are internal 
are free to have their modules unsealed into other internal modules to enable 
modular composition.  APIs that are private and fileprivate do not participate 
in the API boundary because they are not eligible for any kind of export.  

If any of that is unclear, please let me know. 

> This means that it is trivial to put code anywhere within the module that 
> extends the submodule and wraps a symbol in a new name and declares it 
> `public`.  

Precisely.  That’s the same pattern that good Swift code, arguably good code in 
any language that enables hiding, uses today.

> They can also trivially add a `public import MyModule.Foo` anywhere at the 
> top level of their file because every file is forced to include top level 
> scope.

Perhaps you misunderstand.  Say the APIs in MyModule.Foo were all of internal 
or stricter access: The re-export is a no-op.  You cannot change the access 
level of declarations, you can only do the modular thing and wrap them in a 
palatable interface for export by a module you want to be user-facing.  You 
have to decide to make an API public, just as today you have to decide to make 
part of an interface public.  I don’t see how this is distinct from the goals 
of this proposal.

> 
> In my opinion, we need to identify what goals we have for a submodule system 
> - what problems are we trying to solve and what use cases do we intend to 
> enable.  
> 
> There are quite a few of us who want the ability to form solid API boundaries 
> inside a module and view this as one of the fundamental features of a 
> submodule system.  It’s reasonable to ask why we view this capability as 
> essential.
> 
> I can’t speak for anyone else, but here are a few reasons why it’s important 
> to me:
> 
> * Solid API boundaries are essential to good design.  
> * Having access to an entire code base does not reduce the benefits of #1.  
> Some code bases are substantial in size and hard boundaries are important to 
> keeping them manageable.
> * Using full-fledged modules to do this is possible, but also involves a bit 
> of ceremony that is incidental, not essential complexity in many cases.  It 
> would be better to have a lighter weight mechanism to do this.
> * Swift currently only has whole module optimization, not whole program 
> optimization.  There is a performance penalty to using full-fledged modules.
> 
>> 
>> ~Robert Widmann
>> 
>>> On Feb 21, 2017, at 11:38 PM, Matthew Johnson >> > wrote:
>>> 
>>> 
 On Feb 21, 2017, at 10:29 PM, Robert Widmann > wrote:
 
 This level of access, the “private to this submodule except to the select 
 set of interfaces I want to see it” level, is the equivalent of friend 
 classes in C++.  I don’t consider leaving this out to be a hole, nor is it 
 an "encapsulation-related problem” because at no point can you break the 
 API boundary and re-export anything here with a higher level of access 
 than it had previously.
>>> 
>>> By API boundary you mean the top-level module, right?
>>> 
 
> On Feb 21, 2017, at 11:13 PM, Matthew Johnson  > wrote:
> 
> 
>> On Feb 21, 2017, at 10:11 PM, Matthew Johnson > > wrote:
>> 
>> 
>>> On Feb 21, 2017, at 9:47 PM, Brent Royal-Gordon via swift-evolution 
>>> > wrote:

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution
Then let’s discuss that.

You claim Swift has some emphasis on file-oriented programming constructs, I 
argue this is the case locally (fileprivate), but not the case in the language 
as a whole.  Looking more broadly, it is possible to restrict yourself to a 
particular view where one public type resides in one file, but then what to 
make of extensions?  What becomes of “internal” access, which permeates the 
entire module crossing over any file boundaries that might exist?  Today, a 
Swift module can depend on the kinds of files given to the compiler, but there 
is particular emphasis on a module not necessarily being a collection of files, 
but a collection of interfaces all living under the same shared namespace (the 
module name).  A particular facet of that interface set may be freely extended 
by the presence, or contracted by the absence, of a file or files when the 
module is built but one could very well imagine alternative abstractions that 
would serve this purpose just as well - e.g. an in-memory AST.

Maybe what you notice is that you are encouraged (or rather, required) by your 
tools to organize your code a particular way, and this is no mistake.  They 
exist apart from the language itself for a reason, because they themselves 
often depend on the state of the filesystem or the outside world and that 
concern spills over (correctly or not) into your organizational style.  But 
organizational style is just that: we can enable a broader class of programs to 
be designed with the system given here than with one that restricts us to a 
subset of it.  Because let’s not forget, it is actually a subset of the 
functionality presented herein.  If the proposal’s were implemented today, you 
would absolutely be able to design these kinds of modules and tie them to 
filesystem locations.  But you would also be free to group functionality and 
tie a set of files together into the same (sub)module.

> On Feb 21, 2017, at 10:46 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> Well put. As for me, it is not the syntactic delta with which I am concerned. 
> It is just a canary for the organizational delta.
> 
> There are certain freedoms enabled not by the _lack_ of constraints but 
> rather their judicious application. Swift has in the past--and it is your 
> burden to justify why it shouldn't continue to in the future--judged the 
> file-based approach to be one such judicious constraint.
> 
> 
> On Tue, Feb 21, 2017 at 21:42 Robert Widmann <devteam.cod...@gmail.com 
> <mailto:devteam.cod...@gmail.com>> wrote:
>> On Feb 21, 2017, at 10:36 PM, Matthew Johnson <matt...@anandabits.com 
>> <mailto:matt...@anandabits.com>> wrote:
>> 
>>> 
>>> On Feb 21, 2017, at 9:28 PM, Robert Widmann via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>> 
>>>> On Feb 21, 2017, at 10:03 PM, Xiaodi Wu <xiaodi...@gmail.com 
>>>> <mailto:xiaodi...@gmail.com>> wrote:
>>>> 
>>>> On Tue, Feb 21, 2017 at 8:41 PM, Robert Widmann <devteam.cod...@gmail.com 
>>>> <mailto:devteam.cod...@gmail.com>>wrote:
>>>> 
>>>>> On Feb 21, 2017, at 9:37 PM, Xiaodi Wu <xiaodi...@gmail.com 
>>>>> <mailto:xiaodi...@gmail.com>> wrote:
>>>>> 
>>>>> On Tue, Feb 21, 2017 at 8:22 PM, Robert Widmann <devteam.cod...@gmail.com 
>>>>> <mailto:devteam.cod...@gmail.com>>wrote:
>>>>> 
>>>>>> On Feb 21, 2017, at 9:13 PM, Xiaodi Wu <xiaodi...@gmail.com 
>>>>>> <mailto:xiaodi...@gmail.com>> wrote:
>>>>>> 
>>>>>> On Tue, Feb 21, 2017 at 7:59 PM, Robert Widmann via swift-evolution 
>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>>> 
>>>>>>> On Feb 21, 2017, at 7:36 PM, Nevin Brackett-Rozinsky via 
>>>>>>> swift-evolution <swift-evolution@swift.org 
>>>>>>> <mailto:swift-evolution@swift.org>> wrote:
>>>>>>> 
>>>>>>> To my mind, any submodule system for Swift should be designed to 
>>>>>>> relieve the pressure for long files, and make it easy to group tightly 
>>>>>>> related files into a single unit with shared visibility. That way 
>>>>>>> developers can easily organize their code into smaller files while 
>>>>>>> utilizing Swift’s pattern of providing protocol conformances in 
>>>>>>> extensions and keeping implementation details hidden from the rest of 
>>>>>>> the 

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution
By API boundaries I mean both the one internal to MyModule.Foo and the one 
defined by MyModule.  Here “the API boundary” is explicitly about the submodule 
MyModule.Foo, whose internal state may have been “unsealed” in the top level by 
the extension, but has not been re-exported.

~Robert Widmann

> On Feb 21, 2017, at 11:38 PM, Matthew Johnson  wrote:
> 
> 
>> On Feb 21, 2017, at 10:29 PM, Robert Widmann  
>> wrote:
>> 
>> This level of access, the “private to this submodule except to the select 
>> set of interfaces I want to see it” level, is the equivalent of friend 
>> classes in C++.  I don’t consider leaving this out to be a hole, nor is it 
>> an "encapsulation-related problem” because at no point can you break the API 
>> boundary and re-export anything here with a higher level of access than it 
>> had previously.
> 
> By API boundary you mean the top-level module, right?
> 
>> 
>>> On Feb 21, 2017, at 11:13 PM, Matthew Johnson  
>>> wrote:
>>> 
>>> 
 On Feb 21, 2017, at 10:11 PM, Matthew Johnson  
 wrote:
 
 
> On Feb 21, 2017, at 9:47 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> On Feb 21, 2017, at 7:38 PM, Robert Widmann  
>> wrote:
>> 
>> Correct.  Because, in dividing the submodule across an extension, you 
>> have placed what should be a private API into a differently-scoped 
>> location.
> 
> Okay. So is your submodule design not intended to address the "I want to 
> encapsulate implementation details so they're only visible to several 
> units of code in different files, but not the entire module" use case? 
> Because if there's no way to scope a symbol to "everything inside this 
> submodule, but nothing outside this submodule", I think it leaves that 
> use case unserved.
 
 Unless I’m missing something there is also another encapsulation-related 
 problem with the proposed design.  Let’s suppose for the sake of 
 discussion there was a `submoduleprivate` access modifier (intentionally 
 ungainly and not realistic).
 
 // File 1
 module Foo {
 // internal, visible to the whole module
 class Bar { submoduleprivate var protectedState: Int = 0 }
 }
 
 // File 2 - Has nothing to do with Foo at all
 import MyModule.Foo
 
 module NotFoo {
 // Hey, I need to see Bar.protectedState!!!
 func totallyNotFoo() {
var bar = Bar()
bar.foosExposedPrivates = 42
 }
 }
 
 // ok, I’ll just add an extension to Foo so I can see submoduleprivate and 
 wrap what I need
 module Foo {
>>> 
>>> Oops, this should have been `extension Foo`, but otherwise I believe it is 
>>> valid under this proposal.
>>> 
 // Hey, I’ll be nice and keep it fileprivate, but I could make it public 
 if I wanted to.
 extension Foo {
  fileprivate var foosExposedPrivates: Int {
 // Yep, I’m inside Foo so I can see it’s submoduleprivate stuff
 get { return protectedState }
 set  { protectedState = newValue }
  }
 }
 }
 
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> ___
> 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] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution
TJ and I had a proposal 
<https://gist.github.com/CodaFi/42e5e5e94d857547abc381d9a9d0afd6> that would 
have closed this loophole by overhauling qualified imports syntax.

> On Feb 21, 2017, at 11:36 PM, Matthew Johnson <matt...@anandabits.com> wrote:
> 
> 
>> On Feb 21, 2017, at 10:25 PM, Robert Widmann <devteam.cod...@gmail.com 
>> <mailto:devteam.cod...@gmail.com>> wrote:
>> 
>> Good question!  This behavior is actually the behavior that exists today.  
>> For example, open a playground and type
>> 
>> import Foundation.NSDebug
>> 
>> let s : NSString = “"
>> 
>> You’ll notice no matter which submodule you try to visit (Darwin.uuid is 
>> another good example), Swift has decided to insert a top-level import.  We 
>> decided not to change this behavior to maintain source compatibility.
> 
> So there is no way to import a single submodule?  If that is the case why not 
> just disallow the syntax which implies only a single submodule is getting 
> imported and require users to say `import Foo`?  I don’t know what the 
> rationale was for this in the past, but I think it’s undesirable and we’re 
> trying to design something for the future here.
> 
>> 
>> 
>>> On Feb 21, 2017, at 11:21 PM, Matthew Johnson <matt...@anandabits.com 
>>> <mailto:matt...@anandabits.com>> wrote:
>>> 
>>>> 
>>>> On Feb 20, 2017, at 7:56 PM, Robert Widmann via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> Good Evening All,
>>>> 
>>>> Jaden Geller and I have been considering a (sub)module system for Swift 
>>>> that would complement the existing language but also provide sorely needed 
>>>> modularity.  A draft of the proposal is attached to this email, but it can 
>>>> also be read as a gist 
>>>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a> if you 
>>>> desire.
>>>> 
>>>> Cheers,
>>>> 
>>>> ~Robert Widmann
>>>> 
>>>> Modular Swift
>>>> 
>>>> Proposal: SE- <https://gist.github.com/CodaFi/-filename.md>
>>>> Authors: Robert Widmann <https://github.com/codafi>, Jaden Geller 
>>>> <https://github.com/JadenGeller>
>>>> Review Manager: TBD
>>>> Status: Awaiting review
>>>>  
>>>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#introduction>Introduction
>>>> 
>>>> Almost every major programming language supports some form of modular 
>>>> programming through constructs like (sub)modules, packages, or interfaces. 
>>>> Swift, though it provides top-level modules to organize code under, does 
>>>> not provide a complete implementation of any of these concepts, which has 
>>>> led instead to the proliferation of access control levels. This has not 
>>>> proven an effective way to decompose programs into manageable parts, and 
>>>> exposes the need for a real system of modules to solve this modularity 
>>>> problem once and for all.
>>>> 
>>>> Separation of code into distinct islands of functionality should be a 
>>>> first-class construct in the language, not dependent on external files and 
>>>> tools or filesystems. To that end, we propose the introduction of a 
>>>> lightweight module system for Swift.
>>>> 
>>>> Swift-evolution thread 
>>>> 
>>>>  
>>>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#motivation>Motivation
>>>> 
>>>> Swift has reached a point in its evolution where rich libraries and large 
>>>> projects that take on many dependencies have matured significantly. To 
>>>> accomodate the information-hiding and semantics-signalling needs of these 
>>>> users at the time, Swift began its access control story with just three 
>>>> access modifiers: public, private, and internal then grew fileprivate and 
>>>> open as the need to express locality of implementation and 
>>>> "subclassability" arose respectively. In doing so, Swift's access control 
>>>> scheme has become anti-modular.
>>>> 
>>>>  
>>>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#proposed-solution>Proposed
>>>>  solution
>>>> 
>>>> We propose the introduction of a ligh

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution
This level of access, the “private to this submodule except to the select set 
of interfaces I want to see it” level, is the equivalent of friend classes in 
C++.  I don’t consider leaving this out to be a hole, nor is it an 
"encapsulation-related problem” because at no point can you break the API 
boundary and re-export anything here with a higher level of access than it had 
previously.

> On Feb 21, 2017, at 11:13 PM, Matthew Johnson  wrote:
> 
> 
>> On Feb 21, 2017, at 10:11 PM, Matthew Johnson  wrote:
>> 
>> 
>>> On Feb 21, 2017, at 9:47 PM, Brent Royal-Gordon via swift-evolution 
>>>  wrote:
>>> 
 On Feb 21, 2017, at 7:38 PM, Robert Widmann  
 wrote:
 
 Correct.  Because, in dividing the submodule across an extension, you have 
 placed what should be a private API into a differently-scoped location.
>>> 
>>> Okay. So is your submodule design not intended to address the "I want to 
>>> encapsulate implementation details so they're only visible to several units 
>>> of code in different files, but not the entire module" use case? Because if 
>>> there's no way to scope a symbol to "everything inside this submodule, but 
>>> nothing outside this submodule", I think it leaves that use case unserved.
>> 
>> Unless I’m missing something there is also another encapsulation-related 
>> problem with the proposed design.  Let’s suppose for the sake of discussion 
>> there was a `submoduleprivate` access modifier (intentionally ungainly and 
>> not realistic).
>> 
>> // File 1
>> module Foo {
>>   // internal, visible to the whole module
>>   class Bar { submoduleprivate var protectedState: Int = 0 }
>> }
>> 
>> // File 2 - Has nothing to do with Foo at all
>> import MyModule.Foo
>> 
>> module NotFoo {
>>  // Hey, I need to see Bar.protectedState!!!
>>  func totallyNotFoo() {
>>  var bar = Bar()
>>  bar.foosExposedPrivates = 42
>>  }
>> }
>> 
>> // ok, I’ll just add an extension to Foo so I can see submoduleprivate and 
>> wrap what I need
>> module Foo {
> 
> Oops, this should have been `extension Foo`, but otherwise I believe it is 
> valid under this proposal.
> 
>>   // Hey, I’ll be nice and keep it fileprivate, but I could make it public 
>> if I wanted to.
>>   extension Foo {
>>fileprivate var foosExposedPrivates: Int {
>>   // Yep, I’m inside Foo so I can see it’s submoduleprivate stuff
>>   get { return protectedState }
>>   set  { protectedState = newValue }
>>}
>>   }
>> }
>> 
>>> 
>>> -- 
>>> Brent Royal-Gordon
>>> Architechies
>>> 
>>> ___
>>> 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] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution
Good question!  This behavior is actually the behavior that exists today.  For 
example, open a playground and type

import Foundation.NSDebug

let s : NSString = “"

You’ll notice no matter which submodule you try to visit (Darwin.uuid is 
another good example), Swift has decided to insert a top-level import.  We 
decided not to change this behavior to maintain source compatibility.


> On Feb 21, 2017, at 11:21 PM, Matthew Johnson <matt...@anandabits.com> wrote:
> 
>> 
>> On Feb 20, 2017, at 7:56 PM, Robert Widmann via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> Good Evening All,
>> 
>> Jaden Geller and I have been considering a (sub)module system for Swift that 
>> would complement the existing language but also provide sorely needed 
>> modularity.  A draft of the proposal is attached to this email, but it can 
>> also be read as a gist 
>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a> if you 
>> desire.
>> 
>> Cheers,
>> 
>> ~Robert Widmann
>> 
>> Modular Swift
>> 
>> Proposal: SE- <https://gist.github.com/CodaFi/-filename.md>
>> Authors: Robert Widmann <https://github.com/codafi>, Jaden Geller 
>> <https://github.com/JadenGeller>
>> Review Manager: TBD
>> Status: Awaiting review
>>  
>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#introduction>Introduction
>> 
>> Almost every major programming language supports some form of modular 
>> programming through constructs like (sub)modules, packages, or interfaces. 
>> Swift, though it provides top-level modules to organize code under, does not 
>> provide a complete implementation of any of these concepts, which has led 
>> instead to the proliferation of access control levels. This has not proven 
>> an effective way to decompose programs into manageable parts, and exposes 
>> the need for a real system of modules to solve this modularity problem once 
>> and for all.
>> 
>> Separation of code into distinct islands of functionality should be a 
>> first-class construct in the language, not dependent on external files and 
>> tools or filesystems. To that end, we propose the introduction of a 
>> lightweight module system for Swift.
>> 
>> Swift-evolution thread 
>>  
>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#motivation>Motivation
>> 
>> Swift has reached a point in its evolution where rich libraries and large 
>> projects that take on many dependencies have matured significantly. To 
>> accomodate the information-hiding and semantics-signalling needs of these 
>> users at the time, Swift began its access control story with just three 
>> access modifiers: public, private, and internal then grew fileprivate and 
>> open as the need to express locality of implementation and "subclassability" 
>> arose respectively. In doing so, Swift's access control scheme has become 
>> anti-modular.
>> 
>>  
>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#proposed-solution>Proposed
>>  solution
>> 
>> We propose the introduction of a lightweight module system for Swift. More 
>> than simply namspaces, a module declaration interacts with Swift's access 
>> control to provide an API boundary that allows better control over an 
>> interface's design.
>> 
>>  
>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#detailed-design>Detailed
>>  design
>> 
>>  
>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#syntax>Syntax
>> 
>> A module is a named region that introduces a lexical scope into which 
>> declarations may be nested. The name of the module can be used to access 
>> these member declarations. A module, like other aggregate structures in 
>> Swift, may be extended with new declarations over one or more translation 
>> units (files).
>> 
>> We propose a new declaration kind, module-decl be added to the language. A 
>> proposed grammar using the new modulekeyword is given below:
>> 
>> GRAMMAR OF A MODULE DECLARATION
>> 
>> module-declaration -> `module` module-identifier module-body
>> module-name -> identifier
>> module-body -> { module-members(opt) }
>> module-members -> module-member module-members(opt)
>> module-member -> declaration | compiler-control-statement
>> GRAMMAR OF A DECLARATION
>> 
>> + declaration -> module-declaration
>>  
>> &l

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution
Whoops, move bar() out of the utility and you get the actual answer here, 
because you want to be able to see this in foo()!

> On Feb 21, 2017, at 10:54 PM, Robert Widmann  wrote:
> 
> This case is unserved because it is anti-modular and a nightmare to maintain. 
>  The actual way to structure this is to factor bar() and baz() into their own 
> utility submodule, or even deeper if necessary, that has as a parent the 
> primary module that wishes to consume them both but not re-export them out to 
> the parent.  For example,
> 
> 
>   // foo.swift
>   import MyMod.Submodule
>   func foo() {
>   bar()
>   }
> 
>   // bar.swift
> 
>// Make my utilities visible in Foo.Submodule, but invisible to the 
> parent.
>import Foo.Submodule.UtilitySubmodule
> 
>   module Submodule {
>   module UtilitySubmodule  {
>   internal func bar() {
>   baz()
> }
>   }
>   }
> 
>   // baz.swift
>   extension Submodule.UtilitySubmodule {  
>   internal func baz() {
>   …
>   }
>   }
> 
> The thought is that it should be as cheap to create submodules to organize 
> interfaces under as it is to create new directories to organize code under.
> 
> Though, this example is a little odd given that you’re defining and importing 
> the same utility submodule.  Really, what you would want to do is declare the 
> utility in its own file/files outside of bar.swift to really take full 
> advantage of the separation afforded here, then consume it internally with 
> the import as written here.
> 
>> On Feb 21, 2017, at 10:47 PM, Brent Royal-Gordon  
>> wrote:
>> 
>>> On Feb 21, 2017, at 7:38 PM, Robert Widmann  
>>> wrote:
>>> 
>>> Correct.  Because, in dividing the submodule across an extension, you have 
>>> placed what should be a private API into a differently-scoped location.
>> 
>> Okay. So is your submodule design not intended to address the "I want to 
>> encapsulate implementation details so they're only visible to several units 
>> of code in different files, but not the entire module" use case? Because if 
>> there's no way to scope a symbol to "everything inside this submodule, but 
>> nothing outside this submodule", I think it leaves that use case unserved.
>> 
>> -- 
>> Brent Royal-Gordon
>> Architechies
>> 
> 

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


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution
This case is unserved because it is anti-modular and a nightmare to maintain.  
The actual way to structure this is to factor bar() and baz() into their own 
utility submodule, or even deeper if necessary, that has as a parent the 
primary module that wishes to consume them both but not re-export them out to 
the parent.  For example,


// foo.swift
import MyMod.Submodule
func foo() {
bar()
}

// bar.swift

// Make my utilities visible in Foo.Submodule, but invisible to the 
parent.
import Foo.Submodule.UtilitySubmodule

module Submodule {
module UtilitySubmodule  {
   internal func bar() {
baz()
  }
   }
}

// baz.swift
extension Submodule.UtilitySubmodule {  
internal func baz() {
…
}
}

The thought is that it should be as cheap to create submodules to organize 
interfaces under as it is to create new directories to organize code under.

Though, this example is a little odd given that you’re defining and importing 
the same utility submodule.  Really, what you would want to do is declare the 
utility in its own file/files outside of bar.swift to really take full 
advantage of the separation afforded here, then consume it internally with the 
import as written here.

> On Feb 21, 2017, at 10:47 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Feb 21, 2017, at 7:38 PM, Robert Widmann  wrote:
>> 
>> Correct.  Because, in dividing the submodule across an extension, you have 
>> placed what should be a private API into a differently-scoped location.
> 
> Okay. So is your submodule design not intended to address the "I want to 
> encapsulate implementation details so they're only visible to several units 
> of code in different files, but not the entire module" use case? Because if 
> there's no way to scope a symbol to "everything inside this submodule, but 
> nothing outside this submodule", I think it leaves that use case unserved.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 

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


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution

> On Feb 21, 2017, at 10:36 PM, Matthew Johnson <matt...@anandabits.com> wrote:
> 
>> 
>> On Feb 21, 2017, at 9:28 PM, Robert Widmann via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>> On Feb 21, 2017, at 10:03 PM, Xiaodi Wu <xiaodi...@gmail.com 
>>> <mailto:xiaodi...@gmail.com>> wrote:
>>> 
>>> On Tue, Feb 21, 2017 at 8:41 PM, Robert Widmann <devteam.cod...@gmail.com 
>>> <mailto:devteam.cod...@gmail.com>>wrote:
>>> 
>>>> On Feb 21, 2017, at 9:37 PM, Xiaodi Wu <xiaodi...@gmail.com 
>>>> <mailto:xiaodi...@gmail.com>> wrote:
>>>> 
>>>> On Tue, Feb 21, 2017 at 8:22 PM, Robert Widmann <devteam.cod...@gmail.com 
>>>> <mailto:devteam.cod...@gmail.com>>wrote:
>>>> 
>>>>> On Feb 21, 2017, at 9:13 PM, Xiaodi Wu <xiaodi...@gmail.com 
>>>>> <mailto:xiaodi...@gmail.com>> wrote:
>>>>> 
>>>>> On Tue, Feb 21, 2017 at 7:59 PM, Robert Widmann via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>>> On Feb 21, 2017, at 7:36 PM, Nevin Brackett-Rozinsky via swift-evolution 
>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>>> 
>>>>>> To my mind, any submodule system for Swift should be designed to relieve 
>>>>>> the pressure for long files, and make it easy to group tightly related 
>>>>>> files into a single unit with shared visibility. That way developers can 
>>>>>> easily organize their code into smaller files while utilizing Swift’s 
>>>>>> pattern of providing protocol conformances in extensions and keeping 
>>>>>> implementation details hidden from the rest of the module at large.
>>>>>> 
>>>>> 
>>>>> Wonderful, because that’s absolutely supported by this proposal.  To 
>>>>> group tightly related files into a single unit, simply declare a 
>>>>> submodule for them and extend it in each of your related files.
>>>>> 
>>>>> It's supported, but it isn't first-class. By this I mean: there are two 
>>>>> distinguishable uses supported by your proposal, lumped together by the 
>>>>> fact that they are both about grouping units of code together. Put 
>>>>> crudely, one use case is grouping lines of code, while the other is about 
>>>>> grouping files of code. The merits of supporting both have already been 
>>>>> debated in this discussion. The issue I'll touch on is supporting both 
>>>>> with the same syntax. The chief drawbacks here are:
>>>>> 
>>>> 
>>>> What exactly would be required to make it first class?  Referencing file 
>>>> names in the module declaration?
>>>> 
>>>>  See below.
>>>>> - It makes sense to use braces to group lines of code, but it makes no 
>>>>> sense to use braces to group files of code; this just causes entire files 
>>>>> to be indented.
>>>>> 
>>>> 
>>>> If braces aren’t used to demarcate scopes, nesting modules becomes 
>>>> ambiguous.
>>>> 
>>>> Again, let's observe the distinction about grouping files vs. grouping 
>>>> lines.
>>>> 
>>>> Grouping files does not require braces: if the intended use of your 
>>>> feature were to label files X, Y, and Z as belonging to one submodule and 
>>>> A, B, and C to another, it would not matter if X, Y, and Z belonged to 
>>>> Foo.Bar and A, B, and C to Foo.Bar.Baz: your syntax would not require 
>>>> braces.
>>>>  
>>>> It’s important to note that indentation is one particular style.  LLVM 
>>>> code style, in particular, chooses not to indent after namespace 
>>>> declarations.  This issue also crops up when dealing with nested type 
>>>> declarations, and I distinctly remember it not being a big enough deal to 
>>>> "fix this" at the time when a proposal to “flatten” these declaration was 
>>>> brought up.
>>>>  
>>>> Mine is not a critique of the syntax itself; I don't particularly care 
>>>> about indents, nor do I mind not indenting namespaces.
>>>> 
>>>>

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution
Correct.  Because, in dividing the submodule across an extension, you have 
placed what should be a private API into a differently-scoped location.

> On Feb 21, 2017, at 10:34 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Feb 21, 2017, at 7:14 PM, Robert Widmann  wrote:
>> 
>> Fileprivate and private are not changing at all.  Their meaning now extends 
>> from “private to this file” and “private to this declaration” respectively 
>> to those meanings plus “unexportable across any module boundary”.  One 
>> implication of this is it is now possible to create module-scoped private 
>> constants, functions, and data structures, which is one of the use-cases 
>> that Daniel Duan mentioned earlier down in the thread.
> 
> So what you are saying is that, in my example:
> 
>   // foo.swift
>   import MyMod.Submodule
>   func foo() {
>   bar()
>   }
> 
>   // bar.swift
>   module Submodule {
>   internal func bar() {
>   baz()
>   }
>   }
> 
>   // baz.swift
>   extension Submodule {   
>   ??? func baz() {
>   …
>   }
>   }
> 
> There is nothing I can put in the `???` slot that will expose `baz()` to 
> `bar()`, but not to `foo()`. Correct?
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 

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


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution
Let’s use some code to illustrate things.  

// FooUtilities.swift
//
// -module-name=Foo
// module Foo {
// Defines Foo.Utilities
module Utilities {
  internal func visibleInThisSubmodule() {}
}
//}

// FooUtilities+MoreUtilities.swift
extension Foo.Utilities {
  private func privateHelper() {
visibleInThisSubmodule()
  }
}



> On Feb 21, 2017, at 10:31 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> On Tue, Feb 21, 2017 at 9:29 PM, Robert Widmann <devteam.cod...@gmail.com 
> <mailto:devteam.cod...@gmail.com>> wrote:
> Once again, internal is your keyword.  An extension allows you to “open and 
> expand” the module boundary here, which is exactly what you want here - to 
> extend this module across file boundaries without showing your cards to an 
> external consumer of your framework. 
> 
> Sorry, I don't understand. Does your design support the use case below? I 
> don't think it does. Are you replying that supporting the use case below is 
> not a goal of your proposal? If so, please just say so.
> 
> 
>> On Feb 21, 2017, at 10:26 PM, Xiaodi Wu <xiaodi...@gmail.com 
>> <mailto:xiaodi...@gmail.com>> wrote:
>> 
>> On Tue, Feb 21, 2017 at 9:08 PM, Robert Widmann via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> Sorry, been replying to multiple sub-threads today.
>> 
>> 
>> For bar(), because you wish to be able to
>> 
>> 1) Not export it across the outermost module boundary
>> 2) But still use it internally
>> 
>> Internal access is required.  Any higher and you would export (violating 1), 
>> any lower and you wouldn’t be able to internally import (violating 2).
>> 
>> For baz(), because you wish to be able to
>> 
>> 1) Not export it across the outermost module boundary,
>> 2) Or even your own internal submodule boundary
>>  
>> 3) But still use it within the same submodule, across different file 
>> boundaries: this is the feature that many people have stated they want to 
>> emerge out of a submodule design.
>> 
>> Private or fileprivate suffices depending on the scoping you wish for it to 
>> have within the file/interface it’s a part of relative to the other APIs in 
>> the submodule.
>> 
>> > On Feb 21, 2017, at 10:04 PM, Brent Royal-Gordon <br...@architechies.com 
>> > <mailto:br...@architechies.com>> wrote:
>> >
>> > I specified two different behaviors for `bar()` and `baz()`. I see now 
>> > that you describe `internal` as having the behavior I want for `bar()`. Is 
>> > there a way I can get the behavior I want for `baz()`?
>> >
>> > --
>> > Brent Royal-Gordon
>> > Sent from my iPhone
>> >
>> > On Feb 21, 2017, at 6:51 PM, Robert Widmann <devteam.cod...@gmail.com 
>> > <mailto:devteam.cod...@gmail.com>> wrote:
>> >
>> >>> What access modifiers do I put on `bar()` and `baz()` so that `MyMod` 
>> >>> can access `bar()` but not `baz()`, and code outside `MyMod` can access 
>> >>> neither `bar()` nor `baz()`?
>> >>>
>> >>
>> >> internal
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <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] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution
Once again, internal is your keyword.  An extension allows you to “open and 
expand” the module boundary here, which is exactly what you want here - to 
extend this module across file boundaries without showing your cards to an 
external consumer of your framework. 

> On Feb 21, 2017, at 10:26 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> On Tue, Feb 21, 2017 at 9:08 PM, Robert Widmann via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> Sorry, been replying to multiple sub-threads today.
> 
> 
> For bar(), because you wish to be able to
> 
> 1) Not export it across the outermost module boundary
> 2) But still use it internally
> 
> Internal access is required.  Any higher and you would export (violating 1), 
> any lower and you wouldn’t be able to internally import (violating 2).
> 
> For baz(), because you wish to be able to
> 
> 1) Not export it across the outermost module boundary,
> 2) Or even your own internal submodule boundary
>  
> 3) But still use it within the same submodule, across different file 
> boundaries: this is the feature that many people have stated they want to 
> emerge out of a submodule design.
> 
> Private or fileprivate suffices depending on the scoping you wish for it to 
> have within the file/interface it’s a part of relative to the other APIs in 
> the submodule.
> 
> > On Feb 21, 2017, at 10:04 PM, Brent Royal-Gordon <br...@architechies.com 
> > <mailto:br...@architechies.com>> wrote:
> >
> > I specified two different behaviors for `bar()` and `baz()`. I see now that 
> > you describe `internal` as having the behavior I want for `bar()`. Is there 
> > a way I can get the behavior I want for `baz()`?
> >
> > --
> > Brent Royal-Gordon
> > Sent from my iPhone
> >
> > On Feb 21, 2017, at 6:51 PM, Robert Widmann <devteam.cod...@gmail.com 
> > <mailto:devteam.cod...@gmail.com>> wrote:
> >
> >>> What access modifiers do I put on `bar()` and `baz()` so that `MyMod` can 
> >>> access `bar()` but not `baz()`, and code outside `MyMod` can access 
> >>> neither `bar()` nor `baz()`?
> >>>
> >>
> >> internal
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <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] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution

> On Feb 21, 2017, at 10:03 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> On Tue, Feb 21, 2017 at 8:41 PM, Robert Widmann <devteam.cod...@gmail.com 
> <mailto:devteam.cod...@gmail.com>>wrote:
> 
>> On Feb 21, 2017, at 9:37 PM, Xiaodi Wu <xiaodi...@gmail.com 
>> <mailto:xiaodi...@gmail.com>> wrote:
>> 
>> On Tue, Feb 21, 2017 at 8:22 PM, Robert Widmann <devteam.cod...@gmail.com 
>> <mailto:devteam.cod...@gmail.com>>wrote:
>> 
>>> On Feb 21, 2017, at 9:13 PM, Xiaodi Wu <xiaodi...@gmail.com 
>>> <mailto:xiaodi...@gmail.com>> wrote:
>>> 
>>> On Tue, Feb 21, 2017 at 7:59 PM, Robert Widmann via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>> On Feb 21, 2017, at 7:36 PM, Nevin Brackett-Rozinsky via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> To my mind, any submodule system for Swift should be designed to relieve 
>>>> the pressure for long files, and make it easy to group tightly related 
>>>> files into a single unit with shared visibility. That way developers can 
>>>> easily organize their code into smaller files while utilizing Swift’s 
>>>> pattern of providing protocol conformances in extensions and keeping 
>>>> implementation details hidden from the rest of the module at large.
>>>> 
>>> 
>>> Wonderful, because that’s absolutely supported by this proposal.  To group 
>>> tightly related files into a single unit, simply declare a submodule for 
>>> them and extend it in each of your related files.
>>> 
>>> It's supported, but it isn't first-class. By this I mean: there are two 
>>> distinguishable uses supported by your proposal, lumped together by the 
>>> fact that they are both about grouping units of code together. Put crudely, 
>>> one use case is grouping lines of code, while the other is about grouping 
>>> files of code. The merits of supporting both have already been debated in 
>>> this discussion. The issue I'll touch on is supporting both with the same 
>>> syntax. The chief drawbacks here are:
>>> 
>> 
>> What exactly would be required to make it first class?  Referencing file 
>> names in the module declaration?
>> 
>>  See below.
>>> - It makes sense to use braces to group lines of code, but it makes no 
>>> sense to use braces to group files of code; this just causes entire files 
>>> to be indented.
>>> 
>> 
>> If braces aren’t used to demarcate scopes, nesting modules becomes ambiguous.
>> 
>> Again, let's observe the distinction about grouping files vs. grouping lines.
>> 
>> Grouping files does not require braces: if the intended use of your feature 
>> were to label files X, Y, and Z as belonging to one submodule and A, B, and 
>> C to another, it would not matter if X, Y, and Z belonged to Foo.Bar and A, 
>> B, and C to Foo.Bar.Baz: your syntax would not require braces.
>>  
>> It’s important to note that indentation is one particular style.  LLVM code 
>> style, in particular, chooses not to indent after namespace declarations.  
>> This issue also crops up when dealing with nested type declarations, and I 
>> distinctly remember it not being a big enough deal to "fix this" at the time 
>> when a proposal to “flatten” these declaration was brought up.
>>  
>> Mine is not a critique of the syntax itself; I don't particularly care about 
>> indents, nor do I mind not indenting namespaces.
>> 
>> What I'm saying is, you would not have chosen to require braces if your 
>> proposed feature were aimed at making the grouping of files into submodules 
>> as simple as possible. You chose to accommodate grouping lines using the 
>> same syntax as grouping files over the simplest design for grouping files. 
>> Make no mistake, this promotes one use over another.
> 
> Ah, I see.  Yes, one of the stated goals is to become filesystem-independent. 
>  We certainly cannot do that by encouraging the alternative.
>  
> Swift's current design is deliberately not file system-independent. A 
> submodule design built on top of Swift could preserve that. Your draft 
> proposal makes two changes: it introduces a design for submodules; and, it 
> eliminates files as a unit of code by default (not least by declaring 
> `fileprivate` redundant). To my mind, you have presented no justification for 
> the second change other than to say t

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution
Fileprivate and private are not changing at all.  Their meaning now extends 
from “private to this file” and “private to this declaration” respectively to 
those meanings plus “unexportable across any module boundary”.  One implication 
of this is it is now possible to create module-scoped private constants, 
functions, and data structures, which is one of the use-cases that Daniel Duan 
mentioned earlier down in the thread.

> On Feb 21, 2017, at 10:12 PM, Brent Royal-Gordon  
> wrote:
> 
> So are private and/or fileprivate changing to mean "visible within current 
> submodule"? Because I specified that baz() is in a type extension, possibly 
> in another file. 
> 
> -- 
> Brent Royal-Gordon
> Sent from my iPhone
> 
>> On Feb 21, 2017, at 7:08 PM, Robert Widmann  wrote:
>> 
>> For baz(), because you wish to be able to
>> 
>> 1) Not export it across the outermost module boundary, 
>> 2) Or even your own internal submodule boundary
>> 
>> Private or fileprivate suffices depending on the scoping you wish for it to 
>> have within the file/interface it’s a part of relative to the other APIs in 
>> the submodule.

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


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution
Sorry, been replying to multiple sub-threads today.


For bar(), because you wish to be able to 

1) Not export it across the outermost module boundary
2) But still use it internally

Internal access is required.  Any higher and you would export (violating 1), 
any lower and you wouldn’t be able to internally import (violating 2).

For baz(), because you wish to be able to

1) Not export it across the outermost module boundary, 
2) Or even your own internal submodule boundary

Private or fileprivate suffices depending on the scoping you wish for it to 
have within the file/interface it’s a part of relative to the other APIs in the 
submodule.

> On Feb 21, 2017, at 10:04 PM, Brent Royal-Gordon  
> wrote:
> 
> I specified two different behaviors for `bar()` and `baz()`. I see now that 
> you describe `internal` as having the behavior I want for `bar()`. Is there a 
> way I can get the behavior I want for `baz()`?
> 
> -- 
> Brent Royal-Gordon
> Sent from my iPhone
> 
> On Feb 21, 2017, at 6:51 PM, Robert Widmann  wrote:
> 
>>> What access modifiers do I put on `bar()` and `baz()` so that `MyMod` can 
>>> access `bar()` but not `baz()`, and code outside `MyMod` can access neither 
>>> `bar()` nor `baz()`?
>>> 
>> 
>> internal

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


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution
What is implied by the definition of `internal` in the proposal (which should, 
as this thread has shown, be stated explicitly) is that by “export” we mean 
“export to clients” across the outermost module-boundary.  Any API that is not 
public is, by definition, not able to cross this outermost boundary.  Internal 
API is allowed to cross internal boundaries if it is imported internally.  
Private and fileprivate API may not, as the name implies, cross file boundaries 
and so cannot be allowed to cross either boundary.

> On Feb 21, 2017, at 9:49 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Feb 21, 2017, at 6:43 PM, Robert Widmann  wrote:
>> 
>> That is not what this proposal requires.  A public API is ripe for 
>> re(export), but if the parent wishes to communicate with its children 
>> without exporting across the module boundary, see the definition of 
>> `internal`.
> 
> I'm not sure whether I'm misunderstanding or we're talking past each other.
> 
> Let me state this really simply. You have some code in a top-level module, 
> `MyMod`:
> 
>   import MyMod.Submodule
>   
>   func foo() {
>   bar()
>   }
> 
> And you have some other code in a submodule:
> 
>   module Submodule {
>   ??? func bar() {
>   baz()
>   }
>   }
> 
> And then—perhaps in a separate file—you have some other code in an extension 
> of the submodule:
> 
>   extension Submodule {   
>   ??? func baz() {
>   …
>   }
>   }
> 
> What access modifiers do I put on `bar()` and `baz()` so that `MyMod` can 
> access `bar()` but not `baz()`, and code outside `MyMod` can access neither 
> `bar()` nor `baz()`?
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 

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


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution

> On Feb 21, 2017, at 9:49 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Feb 21, 2017, at 6:43 PM, Robert Widmann  wrote:
>> 
>> That is not what this proposal requires.  A public API is ripe for 
>> re(export), but if the parent wishes to communicate with its children 
>> without exporting across the module boundary, see the definition of 
>> `internal`.
> 
> I'm not sure whether I'm misunderstanding or we're talking past each other.
> 
> Let me state this really simply. You have some code in a top-level module, 
> `MyMod`:
> 
>   import MyMod.Submodule
>   
>   func foo() {
>   bar()
>   }
> 
> And you have some other code in a submodule:
> 
>   module Submodule {
>   ??? func bar() {
>   baz()
>   }
>   }
> 
> And then—perhaps in a separate file—you have some other code in an extension 
> of the submodule:
> 
>   extension Submodule {   
>   ??? func baz() {
>   …
>   }
>   }
> 
> What access modifiers do I put on `bar()` and `baz()` so that `MyMod` can 
> access `bar()` but not `baz()`, and code outside `MyMod` can access neither 
> `bar()` nor `baz()`?
> 

internal


open and public declarations are exported by a module for consumption by 
clients of the module.
internal declarations scope over the entire module and any derived submodules.
This way you can consume your own interface without it crossing the module 
boundary.

> -- 
> Brent Royal-Gordon
> Architechies
> 

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


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution

> On Feb 21, 2017, at 9:44 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> On Tue, Feb 21, 2017 at 8:32 PM, Robert Widmann <devteam.cod...@gmail.com 
> <mailto:devteam.cod...@gmail.com>> wrote:
> There’s an important distinction between the ability to wall off, and this 
> particular instance of doing so.  By definition, a module allows for the 
> encapsulation and export of a subset of an API, the same way access modifiers 
> allow types to expose an interface.  If the sub-parts of that API must 
> interact, they must by definition share the same concerns and belong together 
> under the same submodule.  If their implementations require separation then 
> further subdivisions can be made with further submodules.  This is the design 
> practice encouraged, and put to good use, by every other language with 
> modules since the heyday of Modula, and breaking that contract by creating 
> unnecessary parent divisions to introduce headaches for yourself is just 
> another case of anti-modular use of a modular system.  There’s nothing we can 
> do to stop you from asking for this, but that also doesn’t excuse the poor 
> design choice here - especially when it can be rectified by reshuffling your 
> own dependency graph.
> 
> Indeed, I won't disagree with you wrt _modules_. I notice you titled this 
> thread "submodules" but propose a syntax that uses the word `module`. Left 
> unsaid, I'd imagine, is that you regard a submodule as a 
> module-within-a-module.
> 
> This is *not*, as I understand it, what most people on this list are asking 
> for wrt _submodules_. Instead, they are asking for a unit of code greater 
> than a file but less than a module. To parallel that new facility, they want 
> an access level greater than fileprivate but less than internal. This draft 
> proposal (in its failure to acknowledge this frequent ask) explicitly but 
> _silently_ rejects those motivations.

So they want to be able to aggregate interfaces and define their exportability, 
while also maintaining the ability to scope a declaration to a particular 
grouping.  This is, quite literally, the semantics we have defined - with 
modules enabling aggregation and `internal` stretching to become this “new” 
access control kind.

> 
>> On Feb 21, 2017, at 9:19 PM, Xiaodi Wu <xiaodi...@gmail.com 
>> <mailto:xiaodi...@gmail.com>> wrote:
>> 
>> On Tue, Feb 21, 2017 at 8:15 PM, Robert Widmann via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Feb 21, 2017, at 7:46 AM, Brent Royal-Gordon via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>>> On Feb 21, 2017, at 1:28 AM, Daniel Duan via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> It has been my hope that a lightweight module system will remove the need 
>>>> for `private` *and* `fileprivate`.
>>> 
>>> I really doubt it will. `private`/`fileprivate` works because you can also 
>>> access `internal` at the same time.
>>> 
>>> What I mean by that is, think about code like this:
>>> 
>>> // Foo.swift
>>> public class Foo {
>>> public init() { … }
>>> 
>>> func doBar() -> Quux {
>>> return helper(in: randomRange())
>>> }
>>> 
>>> private func helper(in range: Range) -> Quux {
>>> …
>>> }
>>> }
>>> 
>>> // Bar.swift
>>> public class Bar {
>>> public static let shared = Bar()
>>> 
>>> func baz(with foo: Foo) {
>>> let quux = foo.doBar()
>>> process(quux)
>>> }
>>> 
>>> private func process(_ quux: Quux) {
>>> …
>>> }
>>> }
>>> 
>>> These classes have `public` APIs that are externally visible, `internal` 
>>> APIs for communicating with each other, and `private` APIs for 
>>> implementation details. Now try to reproduce the same design with 
>>> submodules and `public`/`internal` only:
>>> 
>>> public import MyMod.Foo
>>> public import MyMod.Bar
>>> 
>>> module Foo {
>>> public class Foo {
>>> public init() { … }
>>> 
>>>

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution

> On Feb 21, 2017, at 9:38 PM, Brent Royal-Gordon  
> wrote:
> 
>> On Feb 21, 2017, at 6:09 PM, Robert Widmann  wrote:
>> 
>>> If I'm reading this correctly, you're proposing that the `internal` APIs in 
>>> a submodule should *not* be accessible to enclosing modules. I also don't 
>>> see any indication that you can control who is allowed to import a 
>>> particular submodule.
>>> 
>>> That means that, if you use a submodule to encapsulate internal state, the 
>>> APIs that are available to the parent module are *also* available to any 
>>> rando who feels like importing your submodule. I don't think that's going 
>>> to be a tenable design.
>> 
>> If the state is truly internal, and you are using internal access control, 
>> this is impossible.  The internal state cannot cross the module boundary 
>> unless it is marked public.  If a “random” feels like importing my 
>> submodule, they will not have access to any symbols.
> 
> I think you're missing my point.
> 
> What you appear to be saying is: "If two things need privileged access to 
> each other, they should be in the same module; if they should hide 
> implementation details from each other, they should be in different modules." 
> But it's perfectly possible for two things to *both* need privileged access 
> to some APIs *and* hide implementation details from one another.
> 
> Basically, my objection is, this proposal requires that parent modules only 
> communicate with submodules through fully `public` APIs which are also 
> available outside the module. If you want to encapsulate certain 
> implementation details by putting them in a submodule, you must paradoxically 
> expose other details—the APIs through which the parent module is supposed to 
> interact with the submodule—to the whole world. That restriction conflicts 
> with Swift's important goal of ensuring that libraries only expose API 
> surface they're committed to supporting indefinitely.

That is not what this proposal requires.  A public API is ripe for re(export), 
but if the parent wishes to communicate with its children without exporting 
across the module boundary, see the definition of `internal`.

> 
> Basically, I think that either we need a new access level meaning "visible to 
> the top-level module and all of its submodules, but not to other modules", or 
> we need a way to specify that a submodule is internal-only and shouldn't be 
> importable by outside code. My submodule sketch the other day took the second 
> approach, but I think one or the other is necessary if we want submodules to 
> serve both as public units of API surface and private encapsulators of 
> implementation detail.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 

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


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution

> On Feb 21, 2017, at 9:37 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> On Tue, Feb 21, 2017 at 8:22 PM, Robert Widmann <devteam.cod...@gmail.com 
> <mailto:devteam.cod...@gmail.com>>wrote:
> 
>> On Feb 21, 2017, at 9:13 PM, Xiaodi Wu <xiaodi...@gmail.com 
>> <mailto:xiaodi...@gmail.com>> wrote:
>> 
>> On Tue, Feb 21, 2017 at 7:59 PM, Robert Widmann via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> On Feb 21, 2017, at 7:36 PM, Nevin Brackett-Rozinsky via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> To my mind, any submodule system for Swift should be designed to relieve 
>>> the pressure for long files, and make it easy to group tightly related 
>>> files into a single unit with shared visibility. That way developers can 
>>> easily organize their code into smaller files while utilizing Swift’s 
>>> pattern of providing protocol conformances in extensions and keeping 
>>> implementation details hidden from the rest of the module at large.
>>> 
>> 
>> Wonderful, because that’s absolutely supported by this proposal.  To group 
>> tightly related files into a single unit, simply declare a submodule for 
>> them and extend it in each of your related files.
>> 
>> It's supported, but it isn't first-class. By this I mean: there are two 
>> distinguishable uses supported by your proposal, lumped together by the fact 
>> that they are both about grouping units of code together. Put crudely, one 
>> use case is grouping lines of code, while the other is about grouping files 
>> of code. The merits of supporting both have already been debated in this 
>> discussion. The issue I'll touch on is supporting both with the same syntax. 
>> The chief drawbacks here are:
>> 
> 
> What exactly would be required to make it first class?  Referencing file 
> names in the module declaration?
> 
>  See below.
>> - It makes sense to use braces to group lines of code, but it makes no sense 
>> to use braces to group files of code; this just causes entire files to be 
>> indented.
>> 
> 
> If braces aren’t used to demarcate scopes, nesting modules becomes ambiguous.
> 
> Again, let's observe the distinction about grouping files vs. grouping lines.
> 
> Grouping files does not require braces: if the intended use of your feature 
> were to label files X, Y, and Z as belonging to one submodule and A, B, and C 
> to another, it would not matter if X, Y, and Z belonged to Foo.Bar and A, B, 
> and C to Foo.Bar.Baz: your syntax would not require braces.
>  
> It’s important to note that indentation is one particular style.  LLVM code 
> style, in particular, chooses not to indent after namespace declarations.  
> This issue also crops up when dealing with nested type declarations, and I 
> distinctly remember it not being a big enough deal to "fix this" at the time 
> when a proposal to “flatten” these declaration was brought up.
>  
> Mine is not a critique of the syntax itself; I don't particularly care about 
> indents, nor do I mind not indenting namespaces.
> 
> What I'm saying is, you would not have chosen to require braces if your 
> proposed feature were aimed at making the grouping of files into submodules 
> as simple as possible. You chose to accommodate grouping lines using the same 
> syntax as grouping files over the simplest design for grouping files. Make no 
> mistake, this promotes one use over another.

Ah, I see.  Yes, one of the stated goals is to become filesystem-independent.  
We certainly cannot do that by encouraging the alternative.

> 
>> - Because some lines of code necessarily precede some other lines of code, 
>> it makes sense to declare the first group using `module` and to extend that 
>> with the second group using `extension`. However, because a file of code 
>> does not necessarily precede another file of code, it is arbitrary which 
>> file is surrounded with a `module` declaration and which one is surrounded 
>> with an `extension` declaration.
> 
> Absolutely.  But it is similarly arbitrary which public APIs are exposed in a 
> type declaration and which are exposed in an extension declaration.
> 
> Not entirely, no. Stored properties must be in the type declaration. Enum 
> cases must be in the type declaration. Perhaps you regard these as temporary 
> inconveniences of the current grammar; I see them as quite reasonable ways to 
> give some consistency as to what's written where in a language where types 
> can be retroactively exte

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution

> On Feb 21, 2017, at 9:13 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> On Tue, Feb 21, 2017 at 7:59 PM, Robert Widmann via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
>> On Feb 21, 2017, at 7:36 PM, Nevin Brackett-Rozinsky via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> To my mind, any submodule system for Swift should be designed to relieve the 
>> pressure for long files, and make it easy to group tightly related files 
>> into a single unit with shared visibility. That way developers can easily 
>> organize their code into smaller files while utilizing Swift’s pattern of 
>> providing protocol conformances in extensions and keeping implementation 
>> details hidden from the rest of the module at large.
>> 
> 
> Wonderful, because that’s absolutely supported by this proposal.  To group 
> tightly related files into a single unit, simply declare a submodule for them 
> and extend it in each of your related files.
> 
> It's supported, but it isn't first-class. By this I mean: there are two 
> distinguishable uses supported by your proposal, lumped together by the fact 
> that they are both about grouping units of code together. Put crudely, one 
> use case is grouping lines of code, while the other is about grouping files 
> of code. The merits of supporting both have already been debated in this 
> discussion. The issue I'll touch on is supporting both with the same syntax. 
> The chief drawbacks here are:
> 

What exactly would be required to make it first class?  Referencing file names 
in the module declaration?

> - It makes sense to use braces to group lines of code, but it makes no sense 
> to use braces to group files of code; this just causes entire files to be 
> indented.
> 

If braces aren’t used to demarcate scopes, nesting modules becomes ambiguous.  
It’s important to note that indentation is one particular style.  LLVM code 
style, in particular, chooses not to indent after namespace declarations.  This 
issue also crops up when dealing with nested type declarations, and I 
distinctly remember it not being a big enough deal to "fix this" at the time 
when a proposal to “flatten” these declaration was brought up.

> - Because some lines of code necessarily precede some other lines of code, it 
> makes sense to declare the first group using `module` and to extend that with 
> the second group using `extension`. However, because a file of code does not 
> necessarily precede another file of code, it is arbitrary which file is 
> surrounded with a `module` declaration and which one is surrounded with an 
> `extension` declaration.

Absolutely.  But it is similarly arbitrary which public APIs are exposed in a 
type declaration and which are exposed in an extension declaration.  My hope is 
that the module declaration itself will become the one-stop-shop for re-exports 
and general public bookkeeping just as aggregate declarations are today.  
Module extensions exist to accommodate users that wish to break related 
functionality across files or into separate independent regions within the same 
file for the same reasons type extensions exist.


> 
> Any variables defined with `internal` access will be visible across those 
> files to those extensions and only those extensions (see the section on 
> access control and modules).  Any variables declared fileprivate or private 
> will, obviously, not be visible across these files.  As an example:
> 
> // FooUtilities.swift
> //
> // -module-name=Foo
> // module Foo {
> // Defines Foo.Utilities
> module Utilities {
>   public func exportableOutsideThisSubmodule() {}
>   func visibleInThisSubmodule() {}
>   private func invisibleToOtherFiles() {}
> }
> //}
> 
> // FooUtilities+MoreUtilities.swift
> extension Utilities {
>   private func privateHelper() {
> visibleInThisSubmodule()
>   }
> }
> 
> I’m not sure where you got the impression that we were just trying to make 
> another fileprivate happen.
> 
>> 
>> Nevin
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> <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] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution

> On Feb 21, 2017, at 7:46 AM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>> On Feb 21, 2017, at 1:28 AM, Daniel Duan via swift-evolution 
>>  wrote:
>> 
>> It has been my hope that a lightweight module system will remove the need 
>> for `private` *and* `fileprivate`.
> 
> I really doubt it will. `private`/`fileprivate` works because you can also 
> access `internal` at the same time.
> 
> What I mean by that is, think about code like this:
> 
>   // Foo.swift
>   public class Foo {
>   public init() { … }
> 
>   func doBar() -> Quux {
>   return helper(in: randomRange())
>   }
> 
>   private func helper(in range: Range) -> Quux {
>   …
>   }
>   }
> 
>   // Bar.swift
>   public class Bar {
>   public static let shared = Bar()
> 
>   func baz(with foo: Foo) {
>   let quux = foo.doBar()
>   process(quux)
>   }
>   
>   private func process(_ quux: Quux) {
>   …
>   }
>   }
> 
> These classes have `public` APIs that are externally visible, `internal` APIs 
> for communicating with each other, and `private` APIs for implementation 
> details. Now try to reproduce the same design with submodules and 
> `public`/`internal` only:
> 
>   public import MyMod.Foo
>   public import MyMod.Bar
> 
>   module Foo {
>   public class Foo {
>   public init() { … }
> 
> 
>   ??? func doBar() -> Quux {
>   return helper(in: randomRange())
>   }
> 
>   func helper(in range: Range) -> Quux {
>   …
>   }
>   }
>   }
> 
>   // Bar.swift
>   module Bar {
>   public class Bar {
>   public static let shared = Bar()
>   
>   ??? func baz(with foo: Foo) {
>   let quux = foo.doBar()
>   process(quux)
>   }
>   
>   func process(_ quux: Quux) {
>   …
>   }
>   }
>   }
> 
> The `doBar()` and `baz()` methods have to be either exposed to third parties 
> or kept away from yourself. That's just not viable.
> 

If they must communicate, they can be a part of the same (sub)module.  This 
makes filling in these annotations trivial.  Nobody actually uses modules to 
wall off their own APIs from themselves like this, they use submodules to 
encapsulate the internal parts and surface public APIs in the parent.

module Bar {
public class Foo {
public init() { … }


internal func doBar() -> Quux {
return helper(in: randomRange())
}

internal func helper(in range: Range) -> Quux {
…
}
}
}

// Bar.swift
extension Bar {
public class Bar {
public static let shared = Bar()

internal func baz(with foo: Foo) {
let quux = foo.doBar()
process(quux)
}

internal func process(_ quux: Quux) {
…
}
}
}

> -- 
> Brent Royal-Gordon
> Architechies
> 
> ___
> 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] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution

> On Feb 21, 2017, at 8:00 AM, Brent Royal-Gordon <br...@architechies.com> 
> wrote:
> 
>> On Feb 20, 2017, at 5:56 PM, Robert Widmann via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> The semantics of some existing access control modifiers shall also be 
>> extended to support module declarations:
>> 
>>  • open and public declarations are exported by a module for consumption 
>> by clients of the module.
>>  • internal declarations scope over the entire module and any derived 
>> submodules.
> 
> If I'm reading this correctly, you're proposing that the `internal` APIs in a 
> submodule should *not* be accessible to enclosing modules. I also don't see 
> any indication that you can control who is allowed to import a particular 
> submodule.
> 
> That means that, if you use a submodule to encapsulate internal state, the 
> APIs that are available to the parent module are *also* available to any 
> rando who feels like importing your submodule. I don't think that's going to 
> be a tenable design.

If the state is truly internal, and you are using internal access control, this 
is impossible.  The internal state cannot cross the module boundary unless it 
is marked public.  If a “random” feels like importing my submodule, they will 
not have access to any symbols.

> 
> (I have a couple other objections—I think the keyword ought to be `submodule` 
> if you don't need a top-level `module` declaration, I think there's a lot to 
> be said for a single declaration covering the entire file, and I'm pretty 
> iffy on this entire approach anyway—but this seems like the most serious 
> problem of the bunch.)
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 

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


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-21 Thread Robert Widmann via swift-evolution

> On Feb 21, 2017, at 7:36 PM, Nevin Brackett-Rozinsky via swift-evolution 
>  wrote:
> 
> To my mind, any submodule system for Swift should be designed to relieve the 
> pressure for long files, and make it easy to group tightly related files into 
> a single unit with shared visibility. That way developers can easily organize 
> their code into smaller files while utilizing Swift’s pattern of providing 
> protocol conformances in extensions and keeping implementation details hidden 
> from the rest of the module at large.
> 

Wonderful, because that’s absolutely supported by this proposal.  To group 
tightly related files into a single unit, simply declare a submodule for them 
and extend it in each of your related files.  Any variables defined with 
`internal` access will be visible across those files to those extensions and 
only those extensions (see the section on access control and modules).  Any 
variables declared fileprivate or private will, obviously, not be visible 
across these files.  As an example:

// FooUtilities.swift
//
// -module-name=Foo
// module Foo {
// Defines Foo.Utilities
module Utilities {
  public func exportableOutsideThisSubmodule() {}
  func visibleInThisSubmodule() {}
  private func invisibleToOtherFiles() {}
}
//}

// FooUtilities+MoreUtilities.swift
extension Utilities {
  private func privateHelper() {
visibleInThisSubmodule()
  }
}

I’m not sure where you got the impression that we were just trying to make 
another fileprivate happen.

> 
> Nevin
> ___
> 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] [Proposal][Discussion] Modular Swift

2017-02-20 Thread Robert Widmann via swift-evolution


~Robert Widmann

2017/02/21 2:16、Jonathan Hull <jh...@gbis.com> のメッセージ:

> It is how it interacts with our current access control.  The scope based 
> nature of this will conflict with the file based nature of the stuff left 
> from Swift 2. I am convinced we need to overhaul it in one sweep to fit one 
> metaphor or the other. The more we mix them, the harder it is to wrap your 
> head around.  We can’t keep rehashing it every 6 months, but that is what 
> will happen so long as it stays in this confused state.

How does this conflict?  Moreover, what do you feel we are adding here that 
crosses the line?

This is not a rehash of existing concepts.  We do not deprecate the access 
control scheme, and we don't extend it except to define how symbols can 
indicate they wish to cross/not cross the module boundary.  This is genuinely a 
system to enable modularity at as little cost as we could suss out given 
inspiration from other programming languages. 

tl;dr I don't want to confuse this with the fileprivate debate.  It is possible 
to have physical access control and modularity, they're not mutually exclusive. 
 And the existing access control scheme cannot express the same concepts a real 
module system can, so it's not enough to paint this as a syntactic/physical 
argument.

> 
> I think I would prefer overall trying swift’s file based system because I 
> think we can completely close that with only 1-2 additional concepts (and it 
> would stay conceptually simple).  I would also be fine with switching to a 
> purely type/scope based system with protected, etc…, but I feel like that 
> will need more complexity to get it fully working (e.g. friends), and will 
> end up being a more complex system overall.

The semantics we intend are all there in the proposal.  You can see for 
yourself just how much this will complect the language versus a different 
proposal to redo access entirely.

> 
> Thanks,
> Jon
> 
> 
>>> On Feb 20, 2017, at 11:03 PM, Robert Widmann <devteam.cod...@gmail.com> 
>>> wrote:
>>> 
>>> 
>>>> On Feb 21, 2017, at 2:01 AM, Jonathan Hull <jh...@gbis.com> wrote:
>>>> 
>>>> 
>>>> On Feb 20, 2017, at 10:46 PM, Robert Widmann via swift-evolution 
>>>> <swift-evolution@swift.org> wrote:
>>>> 
>>>> More generally, we need to move access control away as far away from 
>>>> filesystems as possible.  One day, the compiler is going to get ported 
>>>> over to a platform with some bonkers rules that are going to turn around 
>>>> and bite us.
>>> 
>>> This is the key thing which I think is being debated right now.  Swift 2 
>>> defined the file as a unit of compilation and based its elegant system of 
>>> access modifiers on that.  With Swift 3 we have a mix of type/scope based 
>>> modifiers and file based modifiers… and it is super confusing to everyone 
>>> because we have mixed our metaphors.
>>> 
>>> As much as I want modules, I am now convinced that this proposal will only 
>>> make that situation worse.  We need to pick one way (file based) or the 
>>> other (scope based) and commit to it… but either way, it will require a 
>>> larger overhaul to make the system consistent/usable/teachable again.
>>> 
>>> As an analogy, it is like some people are trying to play rock music during 
>>> a classical music concert.  Both are great independently, and different 
>>> people may prefer one or the other… but trying to play them on top of one 
>>> another just results in noise.
>> 
>> Is there anything specifically about this proposal that turns you off, or is 
>> it access control as it stands today?
>> 
>>> 
>>> Thanks,
>>> Jon
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-20 Thread Robert Widmann via swift-evolution
Sounds distressingly anti-modular!

Really, these kinds of hypotheticals can be addressed when the need arises.  
For now it's a hypothetical fear about a hypothetical issue that isn't 
expressible and highly discouraged by this system - why produce an inverted 
dependency when you could simply rebalance the module by moving the declaration 
into a more appropriate scope?  I can assure you, the proposal seeks 
compatibility with the existing access control modifiers, not to have to 
contort them to fit its own goals.

~Robert Widmann

2017/02/21 2:07、Jonathan Hull  のメッセージ:

> 
>> On Feb 20, 2017, at 10:51 PM, Robert Widmann
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-20 Thread Robert Widmann via swift-evolution

> On Feb 21, 2017, at 2:01 AM, Jonathan Hull <jh...@gbis.com> wrote:
> 
> 
>> On Feb 20, 2017, at 10:46 PM, Robert Widmann via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> More generally, we need to move access control away as far away from 
>> filesystems as possible.  One day, the compiler is going to get ported over 
>> to a platform with some bonkers rules that are going to turn around and bite 
>> us.
> 
> This is the key thing which I think is being debated right now.  Swift 2 
> defined the file as a unit of compilation and based its elegant system of 
> access modifiers on that.  With Swift 3 we have a mix of type/scope based 
> modifiers and file based modifiers… and it is super confusing to everyone 
> because we have mixed our metaphors.
> 
> As much as I want modules, I am now convinced that this proposal will only 
> make that situation worse.  We need to pick one way (file based) or the other 
> (scope based) and commit to it… but either way, it will require a larger 
> overhaul to make the system consistent/usable/teachable again.
> 
> As an analogy, it is like some people are trying to play rock music during a 
> classical music concert.  Both are great independently, and different people 
> may prefer one or the other… but trying to play them on top of one another 
> just results in noise.

Is there anything specifically about this proposal that turns you off, or is it 
access control as it stands today?

> 
> Thanks,
> Jon
> 

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


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-20 Thread Robert Widmann via swift-evolution
This was syntax I initially considered, but Jaden swayed me with the idea that 
we already have an `extension` keyword so we may as well use it to match the 
rest of the language.  Repeating the `module` declaration also lends itself 
more to C++-style namespaces, which these are not.  I’m not saying it’s out of 
the question, far from it. It is an alternative we will keep in mind.

~Robert Widmann

> On Feb 21, 2017, at 1:53 AM, Psycho Hedgehog via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> The one thing i don't understand is the point of using extensions to extend 
> modules across multiple files, why not just allow declaring the submodule in 
> multiple files?
> 
>> Le 20 févr. 2017 à 22:48, Jaden Geller via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :
>> 
>> Oh, I see. You’re questioning the motivation of having scope-granularity 
>> submodules at all! My misunderstanding.
>> 
>> I actually hadn’t considered this as added complexity. In my mind, a scoped 
>> module declaration seems more Swifty than a file module declaration. It 
>> builds on the existing syntax in Swift for defining other sorts of scopes, 
>> e.g. types.
>> 
>> Cheers,
>> Jaden Geller
>> 
>>> On Feb 20, 2017, at 10:41 PM, Jonathan Hull via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> 
>>> I think my question is: Why do we want to allow submodules that are smaller 
>>> than a file?  What does that give us to offset the added complexity?
>>> 
>>> Thanks,
>>> Jon
>>> 
>>>> On Feb 20, 2017, at 6:44 PM, Robert Widmann <devteam.cod...@gmail.com 
>>>> <mailto:devteam.cod...@gmail.com>> wrote:
>>>> 
>>>> 
>>>>> On Feb 20, 2017, at 9:36 PM, Jonathan Hull <jh...@gbis.com 
>>>>> <mailto:jh...@gbis.com>> wrote:
>>>>> 
>>>>> What is the rational for having modules covering only part of a file?  
>>>>> Wouldn’t it be less clutter to have an annotation which worked for the 
>>>>> whole file.  At the very least it would be nice to have an option to 
>>>>> spell it in a way that applies to the whole file.  Otherwise, everything 
>>>>> will be indented another level.
>>>> 
>>>> That is a valid spelling (Rust, IIRC, allows that spelling), but one that 
>>>> is easy to miss sitting in a file and makes it confusing to introduce 
>>>> submodules.  If you include the annotation then define a submodule later 
>>>> down in the file, suddenly you have to remember whether you annotated the 
>>>> file or whether the submodule you’ve just written is going into the 
>>>> top-level module.  See:
>>>> 
>>>> // -module-name=Foo
>>>> // module Foo {
>>>> module Bar; // Shorthand for “This file defines Foo.Bar”
>>>> 
>>>> /* Code */
>>>> 
>>>> // This defines “Foo.Bar.Baz”, but would you know that if it appeared 
>>>> below the fold?
>>>> module Baz {}
>>>> //}
>>>> 
>>>> If anything, this can be added later if evolution converges on it.
>>>> 
>>>>> 
>>>>> I would honestly love to see something which just maps modules to 
>>>>> folders/groups for simplicity sake.
>>>>> 
>>>> 
>>>> There is nothing about this scheme that prevents you from organizing your 
>>>> code this way.  However, modulo that particular method of organization, 
>>>> you don’t really gain much as a user of the language by imposing this 
>>>> restriction.
>>>> 
>>>>> I haven’t thought about it too much yet, so I could easily be missing 
>>>>> something obvious...
>>>>> 
>>>>> Thanks,
>>>>> Jon
>>>>> 
>>>>> 
>>>>>> On Feb 20, 2017, at 5:56 PM, Robert Widmann via swift-evolution 
>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>>> 
>>>>>> Good Evening All,
>>>>>> 
>>>>>> Jaden Geller and I have been considering a (sub)module system for Swift 
>>>>>> that would complement the existing language but also provide sorely 
>>>>>> needed modularity.  A draft of the proposal is attached to this email, 
>>>>>>

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-20 Thread Robert Widmann via swift-evolution

> On Feb 21, 2017, at 1:46 AM, Jonathan Hull  wrote:
> 
> 
>> On Feb 20, 2017, at 6:44 PM, Robert Widmann > > wrote:
>> 
>>> 
>>> 
>>> I would honestly love to see something which just maps modules to 
>>> folders/groups for simplicity sake.
>>> 
>> 
>> There is nothing about this scheme that prevents you from organizing your 
>> code this way.  However, modulo that particular method of organization, you 
>> don’t really gain much as a user of the language by imposing this 
>> restriction.
> 
> I think the big gain is that users of IDEs would just be able to graphically 
> organize modules in Xcode.  Non-IDE users could use the finder to organize 
> things into nested folders.  This maps pretty well with the way I organize my 
> code already (others may be different), so it doesn’t add much complexity.
> 

Xcode today is able to do this with nested classes and structures with the 
hierarchy navigator.  Non-IDE users can use grep or (hopefully) some 
syntax-aware plugin system to help them find these declarations.  Really, 
again, this is a design pattern and one that can be enforced by linters.  If we 
were to impose this restriction at the language level it ties this proposal 
down to file system structure and we are explicitly trying to avoid that.

> On a side note, I do think that people will quickly want a way to reference a 
> particular submodule boundary with access modifiers.  It may not be part of 
> this proposal, but it is somewhat inevitable.  We should consider that as we 
> consider this proposal…
> 

Modules are not types, access control makes no sense here.  APIs may be 
exported (or not) across module boundaries, but modules themselves are not 
arbitrary programming constructs nor do we consider them to carry semantic 
weight as in some other ML-likes.  A public module is no different from a 
private module if you can import it.  A private module is no different from a 
public one if you cannot.

> Thanks,
> Jon

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


Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-20 Thread Robert Widmann via swift-evolution

> On Feb 20, 2017, at 11:39 PM, Matthew Johnson <matt...@anandabits.com> wrote:
> 
> Thanks for bringing up submodules Robert.  I agree it's a good time to 
> discuss them.  
> 
> There seem to be two broad approaches to submodules.  One is more of a 
> physical / encapsulation based view and the other is more of a logical / 
> namespace based view.  This proposal falls into the latter group (Brent's 
> pitch falls into the former).
> 
> Before I offer feedback on this proposal I'm wondering if you can provide 
> some solid examples of what benefits you see in the ability of a single file 
> to participate in more than one submodule.  

A single file defining more than one submodule is like a single file defining 
more than one data structure/extension.  If you decide that particular 
functionality deserves to reside in separate areas of concern, but don’t wish 
to break it out into separate files for whatever reason, just don’t.  Can you 
be more specific about the kind of thing you’re looking for?

> And also, what problems do you foresee if a file were restricted to being in 
> a single submodule (or at the top level of the module)?

The top level case is called out in the proposal.  We felt that requiring a 
top-level module declaration in every file to opt-in would be a needless 
complication to the semantics and would introduce an identifier-addressing 
problem.  Specifically, because modules aren’t namespaces we don’t have a way 
to refer to the “anonymous/global" top-level namespace as in C++ with a bare 
::, so this would become ambiguous without additional syntax

// Explicit declaration of top-level module Foo
module Foo {
  // Decls...
}

// Where does this constant live?  How can I address it from within Foo?
// Why isn’t it just a part of Foo?
let string = “Hello World!”

For one-file-per-module, that kind of restriction represents a particular way 
of organizing code and is a design pattern that is supported under this 
proposal.  We just happen to not enforce that particular pattern, and feel that 
it is the job of a linter to do so.  Really, this kind of restriction is to 
ease the mental burden on compiler writers who use it to build compilation unit 
dependency graphs.  Swift already considers all files when building its modules 
because you can extend any type (and now, any module) from any one of them so 
it doesn’t buy us anything other than an arbitrary restriction.

More generally, we need to move access control away as far away from 
filesystems as possible.  One day, the compiler is going to get ported over to 
a platform with some bonkers rules that are going to turn around and bite us.

~ Robert Widmann

> 
> Sent from my iPad
> 
> On Feb 20, 2017, at 7:56 PM, Robert Widmann via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
>> Good Evening All,
>> 
>> Jaden Geller and I have been considering a (sub)module system for Swift that 
>> would complement the existing language but also provide sorely needed 
>> modularity.  A draft of the proposal is attached to this email, but it can 
>> also be read as a gist 
>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a> if you 
>> desire.
>> 
>> Cheers,
>> 
>> ~Robert Widmann
>> 
>> Modular Swift
>> 
>> Proposal: SE- <https://gist.github.com/CodaFi/-filename.md>
>> Authors: Robert Widmann <https://github.com/codafi>, Jaden Geller 
>> <https://github.com/JadenGeller>
>> Review Manager: TBD
>> Status: Awaiting review
>>  
>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#introduction>Introduction
>> 
>> Almost every major programming language supports some form of modular 
>> programming through constructs like (sub)modules, packages, or interfaces. 
>> Swift, though it provides top-level modules to organize code under, does not 
>> provide a complete implementation of any of these concepts, which has led 
>> instead to the proliferation of access control levels. This has not proven 
>> an effective way to decompose programs into manageable parts, and exposes 
>> the need for a real system of modules to solve this modularity problem once 
>> and for all.
>> 
>> Separation of code into distinct islands of functionality should be a 
>> first-class construct in the language, not dependent on external files and 
>> tools or filesystems. To that end, we propose the introduction of a 
>> lightweight module system for Swift.
>> 
>> Swift-evolution thread 
>>  
>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#motivation>Motivation
>> 
>> Swift has reached a point in its evolu

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-20 Thread Robert Widmann via swift-evolution
The same benefits afforded by multiple extensions contained in the same file: 
sometimes you wish for your concerns not to overlap with one another, but feel 
that they do not necessarily warrant being split into separate files.  There 
really isn’t a reason we should enforce separation of submodules in the 
language if we can help it, it’s more the job of a linter.

~Robert Widmann

> On Feb 21, 2017, at 1:41 AM, Jonathan Hull <jh...@gbis.com> wrote:
> 
> I think my question is: Why do we want to allow submodules that are smaller 
> than a file?  What does that give us to offset the added complexity?
> 
> Thanks,
> Jon
> 
>> On Feb 20, 2017, at 6:44 PM, Robert Widmann <devteam.cod...@gmail.com 
>> <mailto:devteam.cod...@gmail.com>> wrote:
>> 
>> 
>>> On Feb 20, 2017, at 9:36 PM, Jonathan Hull <jh...@gbis.com 
>>> <mailto:jh...@gbis.com>> wrote:
>>> 
>>> What is the rational for having modules covering only part of a file?  
>>> Wouldn’t it be less clutter to have an annotation which worked for the 
>>> whole file.  At the very least it would be nice to have an option to spell 
>>> it in a way that applies to the whole file.  Otherwise, everything will be 
>>> indented another level.
>> 
>> That is a valid spelling (Rust, IIRC, allows that spelling), but one that is 
>> easy to miss sitting in a file and makes it confusing to introduce 
>> submodules.  If you include the annotation then define a submodule later 
>> down in the file, suddenly you have to remember whether you annotated the 
>> file or whether the submodule you’ve just written is going into the 
>> top-level module.  See:
>> 
>> // -module-name=Foo
>> // module Foo {
>> module Bar; // Shorthand for “This file defines Foo.Bar”
>> 
>> /* Code */
>> 
>> // This defines “Foo.Bar.Baz”, but would you know that if it appeared below 
>> the fold?
>> module Baz {}
>> //}
>> 
>> If anything, this can be added later if evolution converges on it.
>> 
>>> 
>>> I would honestly love to see something which just maps modules to 
>>> folders/groups for simplicity sake.
>>> 
>> 
>> There is nothing about this scheme that prevents you from organizing your 
>> code this way.  However, modulo that particular method of organization, you 
>> don’t really gain much as a user of the language by imposing this 
>> restriction.
>> 
>>> I haven’t thought about it too much yet, so I could easily be missing 
>>> something obvious...
>>> 
>>> Thanks,
>>> Jon
>>> 
>>> 
>>>> On Feb 20, 2017, at 5:56 PM, Robert Widmann via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> Good Evening All,
>>>> 
>>>> Jaden Geller and I have been considering a (sub)module system for Swift 
>>>> that would complement the existing language but also provide sorely needed 
>>>> modularity.  A draft of the proposal is attached to this email, but it can 
>>>> also be read as a gist 
>>>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a> if you 
>>>> desire.
>>>> 
>>>> Cheers,
>>>> 
>>>> ~Robert Widmann
>>>> 
>>>> Modular Swift
>>>> 
>>>> Proposal: SE- <https://gist.github.com/CodaFi/-filename.md>
>>>> Authors: Robert Widmann <https://github.com/codafi>, Jaden Geller 
>>>> <https://github.com/JadenGeller>
>>>> Review Manager: TBD
>>>> Status: Awaiting review
>>>>  
>>>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#introduction>Introduction
>>>> 
>>>> Almost every major programming language supports some form of modular 
>>>> programming through constructs like (sub)modules, packages, or interfaces. 
>>>> Swift, though it provides top-level modules to organize code under, does 
>>>> not provide a complete implementation of any of these concepts, which has 
>>>> led instead to the proliferation of access control levels. This has not 
>>>> proven an effective way to decompose programs into manageable parts, and 
>>>> exposes the need for a real system of modules to solve this modularity 
>>>> problem once and for all.
>>>> 
>>>> Separation of code into distinct islands of functionality should be a 
>>>> first-class cons

Re: [swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-20 Thread Robert Widmann via swift-evolution

> On Feb 20, 2017, at 9:36 PM, Jonathan Hull <jh...@gbis.com> wrote:
> 
> What is the rational for having modules covering only part of a file?  
> Wouldn’t it be less clutter to have an annotation which worked for the whole 
> file.  At the very least it would be nice to have an option to spell it in a 
> way that applies to the whole file.  Otherwise, everything will be indented 
> another level.

That is a valid spelling (Rust, IIRC, allows that spelling), but one that is 
easy to miss sitting in a file and makes it confusing to introduce submodules.  
If you include the annotation then define a submodule later down in the file, 
suddenly you have to remember whether you annotated the file or whether the 
submodule you’ve just written is going into the top-level module.  See:

// -module-name=Foo
// module Foo {
module Bar; // Shorthand for “This file defines Foo.Bar”

/* Code */

// This defines “Foo.Bar.Baz”, but would you know that if it appeared below the 
fold?
module Baz {}
//}

If anything, this can be added later if evolution converges on it.

> 
> I would honestly love to see something which just maps modules to 
> folders/groups for simplicity sake.
> 

There is nothing about this scheme that prevents you from organizing your code 
this way.  However, modulo that particular method of organization, you don’t 
really gain much as a user of the language by imposing this restriction.

> I haven’t thought about it too much yet, so I could easily be missing 
> something obvious...
> 
> Thanks,
> Jon
> 
> 
>> On Feb 20, 2017, at 5:56 PM, Robert Widmann via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> Good Evening All,
>> 
>> Jaden Geller and I have been considering a (sub)module system for Swift that 
>> would complement the existing language but also provide sorely needed 
>> modularity.  A draft of the proposal is attached to this email, but it can 
>> also be read as a gist 
>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a> if you 
>> desire.
>> 
>> Cheers,
>> 
>> ~Robert Widmann
>> 
>> Modular Swift
>> 
>> Proposal: SE- <https://gist.github.com/CodaFi/-filename.md>
>> Authors: Robert Widmann <https://github.com/codafi>, Jaden Geller 
>> <https://github.com/JadenGeller>
>> Review Manager: TBD
>> Status: Awaiting review
>>  
>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#introduction>Introduction
>> 
>> Almost every major programming language supports some form of modular 
>> programming through constructs like (sub)modules, packages, or interfaces. 
>> Swift, though it provides top-level modules to organize code under, does not 
>> provide a complete implementation of any of these concepts, which has led 
>> instead to the proliferation of access control levels. This has not proven 
>> an effective way to decompose programs into manageable parts, and exposes 
>> the need for a real system of modules to solve this modularity problem once 
>> and for all.
>> 
>> Separation of code into distinct islands of functionality should be a 
>> first-class construct in the language, not dependent on external files and 
>> tools or filesystems. To that end, we propose the introduction of a 
>> lightweight module system for Swift.
>> 
>> Swift-evolution thread 
>>  
>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#motivation>Motivation
>> 
>> Swift has reached a point in its evolution where rich libraries and large 
>> projects that take on many dependencies have matured significantly. To 
>> accomodate the information-hiding and semantics-signalling needs of these 
>> users at the time, Swift began its access control story with just three 
>> access modifiers: public, private, and internal then grew fileprivate and 
>> open as the need to express locality of implementation and "subclassability" 
>> arose respectively. In doing so, Swift's access control scheme has become 
>> anti-modular.
>> 
>>  
>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#proposed-solution>Proposed
>>  solution
>> 
>> We propose the introduction of a lightweight module system for Swift. More 
>> than simply namspaces, a module declaration interacts with Swift's access 
>> control to provide an API boundary that allows better control over an 
>> interface's design.
>> 
>>  
>> <https://gist.github.com/CodaFi/cd66b7d70b5cd8e4e8b433fa2ace378a#detailed-design>Detailed
>>  design
>> 
>

[swift-evolution] [Proposal][Discussion] Modular Swift

2017-02-20 Thread Robert Widmann via swift-evolution
Good Evening All,

Jaden Geller and I have been considering a (sub)module system for Swift that 
would complement the existing language but also provide sorely needed 
modularity.  A draft of the proposal is attached to this email, but it can also 
be read as a gist 
 if you desire.

Cheers,

~Robert Widmann

Modular Swift

Proposal: SE- 
Authors: Robert Widmann , Jaden Geller 

Review Manager: TBD
Status: Awaiting review
 
Introduction

Almost every major programming language supports some form of modular 
programming through constructs like (sub)modules, packages, or interfaces. 
Swift, though it provides top-level modules to organize code under, does not 
provide a complete implementation of any of these concepts, which has led 
instead to the proliferation of access control levels. This has not proven an 
effective way to decompose programs into manageable parts, and exposes the need 
for a real system of modules to solve this modularity problem once and for all.

Separation of code into distinct islands of functionality should be a 
first-class construct in the language, not dependent on external files and 
tools or filesystems. To that end, we propose the introduction of a lightweight 
module system for Swift.

Swift-evolution thread 
 
Motivation

Swift has reached a point in its evolution where rich libraries and large 
projects that take on many dependencies have matured significantly. To 
accomodate the information-hiding and semantics-signalling needs of these users 
at the time, Swift began its access control story with just three access 
modifiers: public, private, and internal then grew fileprivate and open as the 
need to express locality of implementation and "subclassability" arose 
respectively. In doing so, Swift's access control scheme has become 
anti-modular.

 
Proposed
 solution

We propose the introduction of a lightweight module system for Swift. More than 
simply namspaces, a module declaration interacts with Swift's access control to 
provide an API boundary that allows better control over an interface's design.

 
Detailed
 design

 Syntax

A module is a named region that introduces a lexical scope into which 
declarations may be nested. The name of the module can be used to access these 
member declarations. A module, like other aggregate structures in Swift, may be 
extended with new declarations over one or more translation units (files).

We propose a new declaration kind, module-decl be added to the language. A 
proposed grammar using the new modulekeyword is given below:

GRAMMAR OF A MODULE DECLARATION

module-declaration -> `module` module-identifier module-body
module-name -> identifier
module-body -> { module-members(opt) }
module-members -> module-member module-members(opt)
module-member -> declaration | compiler-control-statement
GRAMMAR OF A DECLARATION

+ declaration -> module-declaration
 
General
 Semantics

Syntax and semantics for imports, as it already supports referencing submodules 
imported from C and Objective-C modules, remains unchanged:

// The outermost module is given explicitly 
// by passing `-module-name=Foo` or exists implicitly, as today.
// module Foo {
public class A {}

module Bar {
  module Baz {
public class C {}
  }

  public class B {}
}

let message = "Hello, Wisconsin!"
// } // End declarations added to module Foo.
To consume this interface:

// imports all of Foo, Foo.Bar, and Foo.Bar.Baz
import Foo.Bar.Baz

// imports Foo.A as A
import class Foo.A
// imports Foo.Bar.B as B
import class Foo.Bar.B
// imports Foo.Bar.Baz.C as C
import class Foo.Bar.Baz.C
A module declaration may only appear as a top-level entity or as a member of 
another module declaration. The following code is therefore invalid:

module Foo {
  class Bar {
module Baz {} // error: module declaration cannot be nested inside type 
'Bar'
  }
}
To extend an existing module declaration, simply reference its module name in 
an extension declaration. 

// In module 'Foo'
module Bar {
  public class A {}

  module Baz {}
}

extension Bar {
  public struct B {}
}

extension Bar.Baz {
  public enum C { case D }
}
 
Modules
 and Access Control

The semantics of some existing access control modifiers shall also be extended 
to support module 

Re: [swift-evolution] [Pitch] Let's talk about submodules

2017-02-20 Thread Robert Widmann via swift-evolution
You’ll be delighted to know, then, that I’ve been thinking about this for a few 
weeks now and have a draft proposal that will be submitted for discussion 
shortly.  I believe this can be an additive feature and still preserve all the 
goodness you would expect of a real module system.

~Robert Widmann

> On Feb 20, 2017, at 8:36 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
> Okay, lots of people want to have some kind of submodule feature, so I'd like 
> to sketch one out so we can hopefully agree on what submodules might look 
> like.
> 
> ***
> 
> Any group of Swift files can be grouped together to form a submodule. 
> Submodules belong within a particular module, and have a dotted name: If 
> `ModKit` is a module, it might have a submodule called `ModKit.Foo`. 
> Submodules can be nested within one another: `ModKit.Foo.Bar` is a submodule 
> of `ModKit.Foo`, which is a submodule of `ModKit`.
> 
> No new access levels are necessary. `internal` APIs are only visible within 
> the submodule they're declared in; a module cannot see its submodules' 
> `internal` APIs, and a submodule cannot see its parent module's `internal` 
> APIs. If a submodule wants to expose some of its APIs to its parent or 
> sibling modules, it must mark them as `public` or `open`. Then they can 
> import the submodule to see its APIs:
> 
>   import ModKit.Foo
> 
> By default, outside modules cannot import a submodule. But an import in the 
> parent module can be decorated by an access control keyword to allow that:
> 
>   /// Any module outside ModKit can import ModKit.Foo and access its 
> `public` and `open` APIs.
>   open import ModKit.Foo
> 
>   /// Any module outside ModKit can import ModKit.Foo and access its 
> `public` and `open` APIs, 
>   /// except `open` APIs are treated as `public`.
>   public import ModKit.Foo
> 
> Imports may also be decorated by the `@exported` attribute, which exposes the 
> submodule's APIs as though they were parent module APIs:
> 
>   @exported open import ModKit.Foo
> 
>   @exported public import ModKit.Foo
> 
> (This is sort of half-implemented already in a buggy `@_exported` attribute.)
> 
> Finally, the standard syntax for importing individual symbols can be used to 
> cherry-pick types to treat differently:
> 
>   // Most ModKit.Foo APIs are not importable...
>   import ModKit.Foo
> 
>   // ...but SomeEnum can be imported as public...
>   public import enum ModKit.Foo.SomeEnum
> 
>   // ...SomeClass can be imported as open...
>   open import class ModKit.Foo.SomeClass
> 
>   // And ImportantStruct will import whenever you import ModKit.
>   @exported public import struct ModKit.Foo.ImportantStruct
> 
> (This syntax should be enhanced to allow cherry-picked importing of global 
> functions, constants, and variables.)
> 
> If there are several different `import`s covering the same submodule or 
> submodule symbol, the most permissive one wins.
> 
> (In large projects, `public`, `open`, and `@exported` imports will most 
> likely all be put in a single Policy.swift file or something, but this is not 
> enforced by the language.)
> 
> A submodule may not import any direct parent module (parent, grandparent, 
> etc.), but may import any other submodule in the same module. This list shows 
> permitted imports for a project with four modules/submodules:
> 
>   ModKit
>   - ModKit.Foo
>   - ModKit.Foo.Bar
>   - ModKit.Quux
>   ModKit.Foo
>   - ModKit.Foo.Bar
>   - ModKit.Quux
>   ModKit.Foo.Bar
>   - ModKit.Quux
>   ModKit.Quux
>   - ModKit.Foo
>   - ModKit.Foo.Bar
> 
> However, submodules may not form circular dependencies through imports—if 
> `ModKit.Quux` imports `ModKit.Foo`, then `ModKit.Foo` cannot import 
> `ModKit.Quux`. The `#if canImport()` feature cannot be used to probe for 
> other submodules within the same top-level module you're in.
> 
> At the compiler driver level, a submodule is specified by giving a 
> `-module-name` parameter with a dot in it. When a file is compiled, only the 
> filenames of the other .swift files in the same module are specified, along 
> with .o files for any submodules; then all the .o files within that submodule 
> are linked into a single .o file for the whole submodule. So files in 
> `ModKit.Foo` would be compiled with only the .swift files in `ModKit.Foo` and 
> the .o file for `ModKit.Foo.Bar`; then all the `ModKit.Foo` .o files would be 
> linked into one .o file for the top-level `ModKit` to use. None of 
> `ModKit.Foo`'s .swift files would be included in the command line when 
> compiling the top-level `ModKit` module.
> 
> (That bit is kind of speculative—particularly the idea of linking submodule 
> files into a single .o file—but I think something like what I'm describing 
> could work.)
> 
> Because the compiler driver is used to 

Re: [swift-evolution] [Fake-Proposal] Remove enums with associated objects

2017-02-20 Thread Robert Widmann via swift-evolution
A lot of problems look algebra-like.  Best to have sums and products at your 
disposal.

 Cheekily,

~Robert Widmann

2017/02/20 15:07、Tino Heth via swift-evolution  
のメッセージ:

> Obviously, this won't become an accepted proposal -  neither the time nor the 
> author would be appropriate for such a result.
> But the list seems a little bit bored lately, so maybe a relaxed discussion 
> without practical implications isn't the worst thing to have now ;-)
> 
> Several current threads seem to cry for sum types, so imho it is a valid 
> question what's wrong with them, and why Swift prefers enums instead.
> 
> I'm sure such a debate already happened, but I haven't seen its arguments... 
> and the ones that come to my mind don't fit to reality:
> Enums might be more powerful, but imho Optional feels more like 
> a burden.
> Sum types, on the other hand, can be composed on the fly and could save us 
> from several, incompatible implementations of trivial things like Result or 
> JSONValue.
> 
> So, what is the big advantage of enums?
> ___
> 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] A compiler option to warn if a closure captures a strong reference to a class instance?

2017-02-20 Thread Robert Widmann via swift-evolution
It's important to note that strong captures by default are correct and not the 
issue here.  It is reference cycles that are the problem.  This feature has 
been requested before, and SR-1807 has been filed for it.  

(For what it's worth, I started working on this a while ago, and a branch 
tracking this is here: 
https://github.com/apple/swift/compare/master...CodaFi:hammer-and-cycle).

~Robert Widmann

2017/02/20 6:22、Lauri Lehmijoki via swift-evolution  
のメッセージ:

> I'm developing an application where we use RxSwift heavily. RxSwift is a 
> stream library. Consequently, closures that we pass to its combinators often 
> live infinitely (this is because one can use RxSwift to represent infinitely 
> long sequences in time). 
> 
> Closures with infinite lifespan have implications for the question "what is 
> the best reference capture mode for closures". My experience is that in 
> RxSwift applications, the current default (strong) is almost always 
> suboptimal. It leads to difficult-to-detect memory leaks and introduces a 
> "gotcha" factor to programmers who are new to Swift. I'd prefer the default 
> to be weak capture.
> 
> So, I'd like to ask you two things:
> 
> A) By default, why the Swift closure captures values strongly?
> B) Should we add a compiler option that, when turned on, would emit a warning 
> if a closure strongly captures a class instance?
> 
> Regards
> Lauri
> ___
> 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] @testable private members

2017-02-18 Thread Robert Widmann via swift-evolution
@testable is already a hack.  Why not just extend it to fileprivate members?

~Robert Widmann

> On Feb 18, 2017, at 1:14 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> When writing unit tests sometimes it is necessary to artificially elevate a 
> member to `internal` in order to make it visible to unit tests where it could 
> otherwise be `private` or `fileprivate`.  We could introduce an `@testable` 
> attribute that could be applied anywhere an access modifier is used.  This 
> attribute would elevate the access modifier to `internal` when the module is 
> imported using the `@testable import MyModule` syntax in a test suite.
> 
> Is this something that others have interest in?  Is it something that might 
> be considered for Swift 4 now that phase 2 has begun?
> 
> Matthew
> ___
> 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] Support for pure functions. Part n + 1.

2017-02-16 Thread Robert Widmann via swift-evolution


> On Feb 16, 2017, at 12:30 PM, Rien via swift-evolution 
>  wrote:
> 
> In essence this is about assistance from the compiler that a function marked 
> ‘pure’ is indeed pure?
> I.e. an error message should be generated when a function marked as ‘pure’ is 
> in fact not ‘pure’?
> 
> If the answer to both questions is ‘yes’ then -not surprising- its a -1 from 
> me.
> 
> Unless there are other benefits?

This feature already exists 

 in a certain sense - via the @effects annotation - but is undocumented, highly 
unstable, and does not entail any semantic checking.  I think that at least 
indicates a desire, even if it’s only in the lower-level parts of SIL now, to 
have some way to determine the “purity” of a function to perhaps guide an 
inliner or future block fusion pass.  Perhaps Andrew Trick can speak more about 
the goals of the annotation and whether it would be ready for prime time as it 
were.  

> 
> Regards,
> Rien
> 
> Site: http://balancingrock.nl
> Blog: http://swiftrien.blogspot.com
> Github: http://github.com/Balancingrock
> Project: http://swiftfire.nl
> 
> 
> 
> 
> 
>> On 16 Feb 2017, at 18:03, T.J. Usiyan via swift-evolution 
>>  wrote:
>> 
>> # Pure Functions
>> 
>> * Proposal: 
>> [SE-](https://github.com/apple/swift-evolution/blob/master/proposals/-name.md)
>> * Author(s): [TJ Usiyan](https://github.com/griotspeak)
>> * Status: **Awaiting review**
>> * Review manager: TBD
>> 
>> ## Introduction
>> 
>> Some functions are, essentially, only meant to be transformations of their 
>> input and–as such–do not and should not reference any variables other than 
>> those passed in. These same functions are not meant to have any effects 
>> other than the aforementioned transformation of input. Currently, Swift 
>> cannot assist the developer and confirm that any given function is one of 
>> these 'pure' functions. To facilitate this, this proposal adds syntax to 
>> signal that a function is 'pure'.
>> 
>> 'pure', in this context, means:
>> 1. The function must have a return value
>> 1. This function can only call other pure functions
>> 1. This function cannot access/modify global or static variables.
>> 
>> ## Motivation
>> 
>> Consider the following example where `_computeNullability(of:)` is meant to 
>> create its output solely based on the provided recognizer.
>> 
>> ```
>> class Recognizer {
>>  var nullabilityMemo: Bool?
>>  var isNullable: Bool {
>>  func _computeNullability(of recognizer: Recognizer) -> Bool {…}
>>  if let back = nullabilityMemo {
>>  return back 
>>  } else {
>>  let back =  _computeNullability(of: self)
>>  nullabilityMemo = back
>>  return back
>>  }
>>  }
>> }
>> ```
>> if `_computeNullability(of:)` is recursive at all, there exists a real 
>> potential to accidentally reference `self` in its body and the mistake, 
>> depending on circumstance, can be terribly subtle. Converting 
>> `_computeNullability(of:)` to a `static` function is an option but 
>> obfuscates the fact that it is *only* to be called within `isNullable`.
>> 
>> 
>> ## Proposed solution
>> 
>> Given the ability to indicate that `_computeNullability(of:)` is a 'pure' 
>> function, the developer gains assurance from the tooling that it doesn't 
>> reference anything or cause any side effects.
>> 
>> 
>> ```
>> class Recognizer {
>>  var nullabilityMemo: Bool?
>>  var isNullable: Bool {
>>  pfunc _computeNullability(of recognizer: Recognizer) -> Bool {…}
>>  if let back = nullabilityMemo {
>>  return back 
>>  } else {
>>  let back =  _computeNullability(of: self)
>>  nullabilityMemo = back
>>  return back
>>  }
>>  }
>> }
>> ```
>> 
>> ## Detailed design
>> 
>> This proposal introduces a new annotation `=>`, which is to be accepted 
>> everywhere `->` currently is. Members created using this kewyord must follow 
>> the rules listed in the introduction.
>> 
>> ## Impact on existing code
>> 
>> This is an additive feature unless alternative 2 is chosen and, as such, 
>> should not require an effect on existing code. It could be used to annotate 
>> closures accepted by methods in the standard library such as `map`, 
>> `filter`, and `reduce`. While this would fit well with their typical use, 
>> such a change is not necessarily part of this proposal.
>> 
>> ## Alternatives considered
>> 
>> It should be noted that neither of these alternatives can remain consistent 
>> for inline closures.
>> 1. keyword `pfunc` (pronounciation: pifəŋk) for 'pure' functions. 
>> 2. `proc` keyword for 'impure' functions and 'func' for 'pure' functions. 
>> This would be a 

Re: [swift-evolution] Proposal to change Logical NOT Operator from exclamation mark ( ! ) to something else

2017-02-15 Thread Robert Widmann via swift-evolution
So you've identified the problem, but what do you propose as a solution here?  

It should be noted that a (non-stdlib) language-level answer to this question 
has already been discussed and rejected 
(https://lists.swift.org/pipermail/swift-evolution/2015-December/32.html).

~Robert Widmann

2017/02/15 9:02、Sadiq via swift-evolution  のメッセージ:

> Hello,
> 
> I would like to suggest to change Logical NOT Operator from ! to something 
> else. 
> It will increase the readability of the code and will avoid any confusion 
> with the symbol used for force unwrapping of optional values. 
> It would be easier for new programmers to learn Swift as the first language. 
> I don't understand the rational behind using the same operator for two 
> different purposes. 
> 
> Thanks and Regards,
> Mohammad Sadiq
> ___
> 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] [swift-users] Plan to move swift-evolution and swift-users mailing lists to Discourse

2017-02-10 Thread Robert Widmann via swift-evolution
 
~Robert Widmann

2017/02/10 3:35、Tino Heth via swift-evolution  
のメッセージ:

> 
>> Easy explained - The problem rises indeed not from the added features but 
>> from the fp group that imposes it’s usage in the Standard libraries and “the 
>> swifty way”. I like many features of Swift (or I wouldn’t be here) but I 
>> don’t want to live in Haskel world. And for some reason these guys become 
>> more and more influential in the community.
> 
> 
> I personally see functional programming as a useful tool that avoids some 
> hard problems, but I have to agree that there is an unhealthy hype about it.
> It is quite common among developers to overuse "new" (fp itself is quite old) 
> toys, and that's ok ― but there are definitely some people who are pushing 
> hard against established concepts like OO, in the deep belief their opinion 
> is the only truth, and that everything else should be abolished.
> I think it's bad for the spirit of the community when members think that way, 
> and even state that those who don't agree with their personal interpretation 
> about what's "swifty" should leave.
> 

This part is shocking to me.  I've been trying to follow this list as best I 
can, and I can't think of a single instance of somebody being asked to leave 
the discussion because they didn't agree with some FP zealotry.  I could be 
wrong, but that's certainly not the kind of community that we should have, and 
you should raise this with the powers that be when you see it.  We should be 
able to disagree but always with the utmost respect for each other's 
experiences.

> That's one reason I don't like the adjective "swifty", but afaics, those who 
> actually decide about the future of Swift have no plans to encourage certain 
> styles by crippling the alternatives.
> 
> Imho the goal should be improvement for everyone:
> Those who like fp, those who like POP, those who like OO… and, of course, for 
> those who like mailing list, as well as for those who hate them.
> ___
> 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] Compile-time generic specialization

2017-02-05 Thread Robert Widmann via swift-evolution
Oh, I see.  The constraint solver is picking an overload that better matches 
the caller rather than the callee's type, which differs from C++ because the 
template expansion process considers specific-type overloads more specific.  We 
don't consider less-generic prototypes than the caller here because we aren't 
performing a (major) syntactic transformation in the process of solving a 
system of type variables.   In order to change the language to adopt this 
feature, Sema would have to have knowledge of the candidate set of 
specializations, either user-specified or SILOptimizer-generated, beforehand.  
It's not impossible to imagine, but it does create an interesting 
backdependency on future potential optimizations, and would potentially majorly 
change the behavior of a Debug or Release build (unless specialization were 
forced at all optimization levels).

~Robert Widmann

2017/02/05 12:37、Abe Schneider  のメッセージ:

> Hi Robert,
> 
> Sorry, I’m not sure I understand your question. In c++ you can do the 
> following:
> 
> struct Storage {};
> struct CBlasStorage: Storage {};
> 
> template  class Tensor {};
> 
> template 
> Tensor dot(const Tensor , const Tensor ) {
>   std::cout << "general version called" << std::endl;
>   Tensor result;
>   return result;
> }
> 
> // specialized version for CBlasStorage
> template <>
> Tensor dot(const Tensor , const 
> Tensor ) {
>   std::cout << "specialized version called" << std::endl;
>   Tensor result;
>   return result;
> }
> 
> // this preserves type information and will call the appropriate `dot`
> template 
> void doSomething(const Tensor , const Tensor ) {
>   auto result = dot(lhs, rhs);
> }
> 
> int main(int argc, char **argv) {
>   Tensor a, b;
>   doSomething(a, b); // we should get "specialized version called"
> }
> 
> 
> The potential equivalent for Swift could look like:
> 
> @_specialize_all
> func dot(_ lhs:Tensor, _ rhs:Tensor) -> Tensor { … }
> 
> Which would cause the compile to create a version of `dot` per S type that it 
> gets called with. Thus, when `doSomething` is called, it would dispatch to 
> that version of `dot`, allowing the type information to be preserved in the 
> same way it does in c++.
> 
> Abe
> 
>> On Feb 5, 2017, at 11:35 AM, Robert Widmann  wrote:
>> 
>> I don't understand how this change would cause method dispatch to invoke a 
>> different prototype.  Specialization in either language mentioned doesn't do 
>> that.
>> 
>> ~Robert Widmann
>> 
>> 2017/02/05 11:28、Abe Schneider via swift-evolution 
>>  のメッセージ:
>> 
>>> Hi all,
>>> 
>>> The current behavior of generics in Swift causes it lose type information 
>>> at compile time due to the desire of maintaining a single version of the 
>>> function. This runs counter to how c++ works, which creates a new copy of a 
>>> function per type, but preserves information to be preserved. This can 
>>> cause unexpected behavior from the user’s perspective:
>>> 
>>>   protocol DispatchType {}
>>>   class DispatchType1: DispatchType {}
>>> 
>>>   func doBar(value:D) {
>>>   print(“General function called")
>>>   }
>>> 
>>>   func doBar(value:DispatchType1) {
>>>   print("DispatchType1 called")
>>>   }
>>> 
>>>   func test(value:D) {
>>>   doBar(value: value)
>>>   }
>>> 
>>>   test(value: d1) // “General function called”, but it’s not obvious why
>>> 
>>> 
>>> The suggested method to get around this issue is to use a protocol to 
>>> create a witness table, allowing for runtime dispatch. However, this 
>>> approach is not ideal in all cases because: (a) the overhead of runtime 
>>> dispatch may not be desirable, especially because this is something that 
>>> can be determined at compile time; and (b) there are some designs in which 
>>> this behavior can complicate things.
>>> 
>>> One example of a design where this behavior can be problematic is when a 
>>> protocol is used to determine what functions get dispatched:
>>> 
>>>   protocol Storage { … }
>>>   class Tensor { … }
>>> 
>>>   class CBlasStorage: Storage { … }
>>>   class OpenCLStorage: Storage { … }
>>> 
>>>   func dot(_ lhs:Tensor, _ rhs:Tensor) -> Tensor { … }
>>> 
>>>   // like behavior, these will not work if called from another generic 
>>> function (but will work for non-generic functions)
>>>   func dot(_ lhs:Tensor, _ rhs:Tensor) -> Tensor where 
>>> S:CBlasStorage { … }
>>>   func dot(_ lhs:Tensor, _ rhs:Tensor) -> Tensor where 
>>> S:OpenCLStorage { … }
>>> 
>>> In this case, depending on the underlying storage, we want an optimized 
>>> version of `dot` to be called. To make this work correctly we can add 
>>> static methods to `Tensor`, but this has several drawbacks: (a) it makes 
>>> the `Tensor` class monolithic, every possible method must be determine a 
>>> priori and be defined in the class; (b) it doesn’t allow new methods to be 
>>> added Tensor without touching the main class; and (c) it unnecessarily 
>>> 

Re: [swift-evolution] Compile-time generic specialization

2017-02-05 Thread Robert Widmann via swift-evolution
I don't understand how this change would cause method dispatch to invoke a 
different prototype.  Specialization in either language mentioned doesn't do 
that.

~Robert Widmann

2017/02/05 11:28、Abe Schneider via swift-evolution  
のメッセージ:

> Hi all,
> 
> The current behavior of generics in Swift causes it lose type information at 
> compile time due to the desire of maintaining a single version of the 
> function. This runs counter to how c++ works, which creates a new copy of a 
> function per type, but preserves information to be preserved. This can cause 
> unexpected behavior from the user’s perspective:
> 
>protocol DispatchType {}
>class DispatchType1: DispatchType {}
> 
>func doBar(value:D) {
>print(“General function called")
>}
> 
>func doBar(value:DispatchType1) {
>print("DispatchType1 called")
>}
> 
>func test(value:D) {
>doBar(value: value)
>}
> 
>test(value: d1) // “General function called”, but it’s not obvious why
> 
> 
> The suggested method to get around this issue is to use a protocol to create 
> a witness table, allowing for runtime dispatch. However, this approach is not 
> ideal in all cases because: (a) the overhead of runtime dispatch may not be 
> desirable, especially because this is something that can be determined at 
> compile time; and (b) there are some designs in which this behavior can 
> complicate things.
> 
> One example of a design where this behavior can be problematic is when a 
> protocol is used to determine what functions get dispatched:
> 
>protocol Storage { … }
>class Tensor { … }
> 
>class CBlasStorage: Storage { … }
>class OpenCLStorage: Storage { … }
> 
>func dot(_ lhs:Tensor, _ rhs:Tensor) -> Tensor { … }
> 
>// like behavior, these will not work if called from another generic 
> function (but will work for non-generic functions)
>func dot(_ lhs:Tensor, _ rhs:Tensor) -> Tensor where 
> S:CBlasStorage { … }
>func dot(_ lhs:Tensor, _ rhs:Tensor) -> Tensor where 
> S:OpenCLStorage { … }
> 
> In this case, depending on the underlying storage, we want an optimized 
> version of `dot` to be called. To make this work correctly we can add static 
> methods to `Tensor`, but this has several drawbacks: (a) it makes the 
> `Tensor` class monolithic, every possible method must be determine a priori 
> and be defined in the class; (b) it doesn’t allow new methods to be added 
> Tensor without touching the main class; and (c) it unnecessarily forces users 
> to user the more verbose `Tensor.dot(a, b)`.
> 
> Point (a) in theory could be made better by creating a `TensorOps` protocols. 
> However, because type constraints cannot currently be placed on extensions, 
> it is not currently possible to implement.
> 
> 
> One potential solution would be to add/extend an attribute for generic 
> functions that would force multiple versions of that function to be created. 
> There is already there is a `@_specialize` attribute, but you have to: (a) 
> manually write out all the cases you want to cover; and (b) only affects the 
> compiled code, which does not change this behavior. Due to the fact that 
> `@_specialize` exists, I’m going to assume it wouldn’t be a major change to 
> the language to extend the behavior to compile-time dispatch.
> 
> 
> Thanks!
> Abe
> ___
> 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] Either protocol syntax

2017-02-02 Thread Robert Widmann via swift-evolution
It sounds like what you want is an GADT-like adaptor gadget to try to bridge 
between these protocols across these specific types.  With general disjuncts 
you’re subject to the open world assumption - that anybody that should conform 
to a (visible) protocol, can conform to that protocol - thus rendering any 
attempts to inspect the kind of thing you’ve got in the disjunct useless.

~Robert Widmann


> On Feb 2, 2017, at 5:02 PM, Rex Fenley via swift-evolution 
>  wrote:
> 
> But then any time as user of the pipeline I'm writing would like a new type 
> of collection they will be forced to inherit this new protocol vs one they're 
> already familiar with and which the collection may already conform too.
> 
> On Thu, Feb 2, 2017 at 1:53 PM, Matthew Johnson  > wrote:
> 
>> On Feb 2, 2017, at 3:46 PM, Rex Fenley > > wrote:
>> 
>> My use case is RLMArray and it can't implement RangeReplaceableCollection 
>> though because `init` is unavailable, additionally, there's a lot of parts 
>> to the protocol that would take some time to implement correctly if I could. 
>> They offer a Swift type List that wraps RLMArray and does a bunch of stuff 
>> to implement RangeReplaceableCollection, but they discourage using their 
>> Swift library in mixed Obj-C/Swift projects and certain model objects simply 
>> couldn't use the List type anyway because they're also used in Obj-C and 
>> List is not @objc compliant.
>> 
>> So this leaves me in situations where when I need to use Array or RLMArray I 
>> have to duplicate my code, not just in one place, but all the way down a 
>> pipeline in order to have my generics work with either 
>> RangeReplaceableCollection or RLMArray.
>> 
>> If I could abstract the commonalities required by my application, I could 
>> just have a RLMArrayProtocol that has RLMArray's exposed function signatures 
>> and a new protocol Appendable = RangeReplaceableCollection | 
>> RLMArrayProtocol and this will type check all the way through the pipeline.
>> 
>> tl;dr - if a function signature required by a protocol is marked unavailable 
>> on a class, then disjunction is necessary in order to bridge the two (or 
>> more) types without duplicating code.
> 
> You should be able to solve this problem today by creating a custom protocol 
> that you use as a constraint in your generic code and providing conformances 
> for both Array and RLMArray.
> 
>> 
>> On Thu, Feb 2, 2017 at 1:35 PM, Matthew Johnson > >wrote:
>>> 
>>> On Feb 2, 2017, at 3:26 PM, Rex Fenley via swift-evolution 
>>> > wrote:
>>> 
>>> Hello, I believe there was some discussion about this quite awhile ago. I 
>>> was wondering if there's any interest in including a protocol 'or' type 
>>> that would be the intersection of two protocols. This could be really 
>>> useful in situations where a framework that the user has no control over 
>>> implements a portion of some often used protocol. Such as specialized 
>>> collections from an Database framework that don't implement 
>>> RangeReplaceableCollection but have a set of methods that are equivalent. 
>>> The user can then implement a protocol that is the intersection of those 
>>> set of methods and not duplicate code.
>> 
>> If the specialized collection in the database framework already provides 
>> functionality equivalent to `RangeReplaceableCollection` what you really 
>> want to do is just provide the conformance you’re looking for in an 
>> extension:
>> 
>> extension SpecializedDatabaseCollection: RangeReplaceableCollection {
>>// if necessary, provide forwarding wrappers where the member names don’t 
>> match up.
>> }
>> 
>> But in a case like this the framework itself really should provide this 
>> conformance out of the box.  If they didn’t, maybe there is a good reason so 
>> you would want to find out why it wasn’t provided.
>> 
>> Is there something you’re hoping to do that you can’t solve by simply 
>> extending the framework types?
>> 
>>> 
>>> Simplified example:
>>> 
>>> protocol Animal {
>>> var hasEars: Bool { get }
>>> func grow()
>>> }
>>> 
>>> protocol Plant {
>>> var isGreen: Bool { get }
>>> func grow()
>>> }
>>> 
>>> protocol LivingThing = Plant | Animal // or a different syntax
>>> 
>>> LivingThing's is as follows
>>> {
>>> func grow()
>>> }
>>> 
>>> -- 
>>> Rex Fenley  |  IOS DEVELOPER
>>> 
>>> 
>>> Remind.com  |  BLOG   |  
>>> FOLLOW US   |  LIKE US 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org 
>>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>>> 

Re: [swift-evolution] Initializers

2017-01-30 Thread Robert Widmann via swift-evolution
This seems to contradict Swift’s goal of being safe by default 
, no?  It would make me incredibly uncomfortable if 
there were a backdoor in DI, even if that backdoor emitted traps when it fails.

> On Jan 28, 2017, at 1:07 PM, Victor Petrescu via swift-evolution 
>  wrote:
> 
> Hello,
> 
> My name is Victor, been a developer (C, delphi, php, java, js) for the last 
> 10 years or so and lately I had the chance to try swift. I have a 
> suggestion/question regarding initializers.
> 
> Sidenote: If this is not the correct mailing list for this can you please 
> redirect me to the right place?
> 
> Consider the following 2 classes and code:
> 
> class A {
>  var x:Int
> 
>  init() {
>  x = 1
>  }
> }
> 
> class B : A {
> override init() {
>  super.init() // Swift FORCES this call
>  x = 2
> }
> }
> 
> var a:B
> for i in 0... {
> a = B()  // Whatever... some code that inits B.
> }
> 
> This results in  x = 1 then  x = 2... the x = 1 being totally 
> useless in this particular case.
> 
> In this case, if you don't make the super init you get a compile error.
> 
> Now... I see the use of this. It ensure that all members are initialized. For 
> example if A had a private variable (another strange choice here with what 
> private means in swift but I haven't thought on it yet so... maybe is a cool 
> choice), the B init could not initialize it. I also understand that the cases 
> when you need this minor performance gain are rather rare (but they do still 
> exist). So I guess the choice for the super.init() had that reasoning.
> 
> Still... my suggestion would be to give a warning, maybe force a key word 
> before the init (like iKnowWhatImDoing init() {}), THEN in case vars are 
> still not inited give a runtime error (afaik Objective C for example gives a 
> warning). That ensures everything is ok and also allows programmers that have 
> strange cases to treat them accordingly.
> 
> Anyway... that would be my suggestion. Maybe this was discussed before 
> also... If this was discussed before can you please point me to the 
> discussion? I like to understand the choices for the tools I use.
> 
> 
> P.S. Please excuse any grammatical errors... English is not my first language.
> 
> Thank you for your time and have a great day,
> Petrescu Victor
> ___
> 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] The lack of namespaces is leading people astray

2017-01-30 Thread Robert Widmann via swift-evolution
I submitted a proposal with TJ a while ago that tried to address this 
comprehensively because the trouble is if you just want submodules you have to 
define how our current penta-scheme of access control interacts with each level 
or do away with a few of them to make some simplifying assumptions.  It also 
raises an ambiguity with qualified imports that has to be worked out.

> On Jan 30, 2017, at 9:00 AM, Adrian Zubarev via swift-evolution 
>  wrote:
> 
> If I remember correctly it has been said that we don't need namespaces in 
> favor of submodules, which schould solve these issues.
> 
> -- 
> Adrian Zubarev
> Sent with Airmail
> Am 30. Januar 2017 um 14:55:31, Tuur Anton via swift-evolution 
> (swift-evolution@swift.org ) schrieb:
> 
>> The lack of namespaces is making people create all kinds of "design 
>> patterns".
>> 
>> struct API {
>> static let endpoint = "http://example.com/api "
>> }
>> 
>> Here is an "improvement" to the above "design pattern" to prevent 
>> instantiating API:
>> 
>> struct API {
>> private init() {}
>> static let endpoint = "http://example.com/api "
>> }
>> 
>> Finally, here is another "improvement" that uses enum instead of struct to 
>> avoid having to write the private initializer:
>> 
>> enum API {
>> static let endpoint = "http://example.com/api "
>> }
>> 
>> I doubt any of you find this beautiful. Yet these "design patterns" (just 
>> hacks IMO) are spreading like the plague because of the lack of namespaces.
>> 
>> What do you think?
>> 
>> ___
>> 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] [Draft] Test-Only Package Dependencies and Targets

2017-01-30 Thread Robert Widmann via swift-evolution

> On Jan 30, 2017, at 2:38 PM, Ankit Agarwal  wrote:
> 
> 
> Not in practice (with respect to package manifests). In fact, it seems that, 
> given there are separate commands (swift build and swift test), separate 
> directories (Sources and Tests), and separate products, that there's a hole 
> to be filled here by separate handling for test suites in package manifests.
> 
> FWIW, overriding conventions will potentially allow you control the layout of 
> the package (when we have that feature).

In that case, as long as there are plans for this kind of feature, I can hold 
off on submitting this proposal until it materializes.

>  
>  
> This is all not to discount the features you've brought up as well, but I'm 
> having trouble seeing why a distinction here is such a problem.
> 
> Could you elaborate on what kind of distinction are you proposing? Is it 
> separating targets and testTargets?

Yes.

> 
> -- 
> Ankit
> 

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


Re: [swift-evolution] Why doesn't Swift allow a variable and a function with the same name?

2017-01-30 Thread Robert Widmann via swift-evolution
This seems like it’s running through the same check that disallows defining and 
calling a closure 

let randomFunc : () -> () = randomFunc()

> On Jan 30, 2017, at 2:37 PM, Michael Gubik via swift-evolution 
>  wrote:
> 
> Example that does not compile:
> 
>let randomArray = randomArray(withCapacity: 4096)
> 
> Compiler error: “Variable used within its own initial value”
> The variable name unfortunately clashes with the function name.
> 
> This problem forces the developer to think about an alternative name.
> IMHO that’s suboptimal since many times the most canonical naming would be 
> one where these two go by the same name.
> 
> It’s not a big problem in practice but I wonder if there are plans to change 
> this?
> 
> 
> Thanks,
> Michael Gubik
> 
> ___
> 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


  1   2   3   >