Re: [swift-evolution] Revisiting SE-0110

2017-05-25 Thread Gwendal Roué via swift-evolution
> Furthermore, this probably comes up most commonly with dictionaries, since 
> they're a sequence of tuples. The element tuple for dictionaries has element 
> labels (key: Key, value: Value), so instead of writing `{ tuple in let (key, 
> value) = tuple; f(key, value) }`, you could use the implicit argument and 
> write `{ f($0.key, $0.value) }`.
> 
> -Joe

I've migrated a project from Swift 3 to Swift 4 (relevant commit: 
https://github.com/groue/GRDB.swift/commit/4f26cbcacf7b783c9c503f2909f2eb03ef7930fe)

Joe is right, dictionaries, as handy as they are, are particularly affected. 
But $0 is hardly a panacea.

What I regret the most with the change is the lost ability to give *relevant 
names* to tuple elements (and sometimes with the forced introduction of a phony 
variable that has no relevant name (like "pair").

Here are below four examples of regressions introduced by SE-0110:

Example 1
-return columns.index { (column, _) in column.lowercased() == 
lowercaseName }
+return columns.index { $0.0.lowercased() == lowercaseName }

Example 2 :
-.map { (mappedColumn, baseColumn) -> (Int, String) in
+.map { (pair) -> (Int, String) in
+let mappedColumn = pair.key
+let baseColumn = pair.value

Example 3 :
-.map { (table, columns) in 
"\(table)(\(columns.sorted().joined(separator: ", ")))" }   
+.map { "\($0.key)(\($0.value.sorted().joined(separator: ", 
")))" }

Example 4 :
-dictionary.first { (column, value) in column.lowercased() == 
orderedColumn.lowercased() }
+dictionary.first { $0.key.lowercased() == 
orderedColumn.lowercased() }

Gwendal Roué

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


[swift-evolution] SE-0168: Multi-Line String Literals

2017-05-25 Thread Dave Yost via swift-evolution

I corresponded with Steve Bourne about here docs a while ago. He said

He said the only reason that indenting was not supported in his shell is that 
he didn’t think of it and neither did the other guys at Cambridge from whom he 
got the idea. And,

> I never considered the indent idea.  It’s a good idea although I don’t like 
> the idea of post processing the temp file to remove the leading white space.  
> I agree the way it is now is not easy to look at and I can't think of a way 
> to have the ident amount specified in advance of reading the document.


He liked this idea: The proposal could be extended so that if the open quote 
marking appears on a line by itself, the indentation on that line rules, and 
all lines through the close quote marking must have the same indenting.

  let foo = 
"""
indent of initial quote
dictates indentation
and must match 
indent of trailing quote
"""

If that proposal is adopted, then there are two alternatives if the open quote 
marking does not appear on a line by itself:
1. The indent is dictated by the close quote marking (current proposal). The 
coder can choose to take the parser performance hit, with apologies to srb.
2. There is no indenting and the close quote must appear flush left. (I don’t 
like this alternative.)

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


Re: [swift-evolution] [Pitch] Computed properties as aliases

2017-05-25 Thread Hooman Mehr via swift-evolution
Agreed. 

Actually, I was thinking about it while writing my response and wanted to go 
back and dig that thread to refresh my memory and bring it up. 

Thank you for taking care of that.

> On May 25, 2017, at 7:33 PM, Charles Srstka  wrote:
> 
>> On May 25, 2017, at 9:26 PM, Hooman Mehr via swift-evolution 
>> > wrote:
>> 
>> This is common when you are using façade design pattern. You use a façade to 
>> flatten and hide the internal composition of a composite object and present 
>> it as a single flat object. In some types of projects this comes up rather 
>> frequently. Both in client / UI programming and server side / business logic.
> 
> You know, what I would like to see instead of this would be a revival of the 
> ‘automatic protocol forwarding’ concept that was pitched here very early on 
> in the swift-evolution process:
> 
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004737.html
>  
> 
> 
> This would be a much more flexible way to solve the same problem, and could 
> also solve some problems that we used to use methods like 
> forwardingTargetForSelector: for in Objective-C.
> 
> Charles
> 

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


Re: [swift-evolution] [Pitch] Computed properties as aliases

2017-05-25 Thread Charles Srstka via swift-evolution
> On May 25, 2017, at 9:26 PM, Hooman Mehr via swift-evolution 
>  wrote:
> 
> This is common when you are using façade design pattern. You use a façade to 
> flatten and hide the internal composition of a composite object and present 
> it as a single flat object. In some types of projects this comes up rather 
> frequently. Both in client / UI programming and server side / business logic.

You know, what I would like to see instead of this would be a revival of the 
‘automatic protocol forwarding’ concept that was pitched here very early on in 
the swift-evolution process:

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151228/004737.html
 


This would be a much more flexible way to solve the same problem, and could 
also solve some problems that we used to use methods like 
forwardingTargetForSelector: for in Objective-C.

Charles

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


Re: [swift-evolution] [Pitch] Computed properties as aliases

2017-05-25 Thread Hooman Mehr via swift-evolution
This is common when you are using façade design pattern. You use a façade to 
flatten and hide the internal composition of a composite object and present it 
as a single flat object. In some types of projects this comes up rather 
frequently. Both in client / UI programming and server side / business logic.

> On May 25, 2017, at 11:34 AM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
>  Is it actually very common? In what sort of programming?

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


Re: [swift-evolution] [Pitch] Computed properties as aliases

2017-05-25 Thread Harshil Shah via swift-evolution
Personally I write a lot of UI code, and so the pattern is used quite a lot to 
expose certain properties, for example a button's `title` and `textColor`.

Oftentimes, the view hierarchy itself is complicated enough that exposing views 
directly is not feasible, so a host of such aliases are needed to offer a 
usable public API.

– Harshil

>> On 26-May-2017, at 1:04 AM, Charles Srstka  wrote:
>> 
>>> On May 25, 2017, at 1:34 PM, Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> 
>>> On Thu, May 25, 2017 at 10:08 AM, Harshil Shah via swift-evolution 
>>>  wrote:
>>> Hi all,
>>> 
>>> The idea behind this is to add a shorter, cleaner syntax for the common 
>>> pattern of using computed properties to provide public API for properties 
>>> of private variables.
>>> 
>>> For example:
>>> 
>>> public var foo: Type {
>>> get { return privateBar.baz }
>>> set { privateBar.baz = newValue }
>>> }
>>> 
>>> While this is a great improvement over the previous convention of 
>>> `someVar:` and `setSomeVar:` as found in a lot of UIKit, it still has some 
>>> issues.
>>> 
>>> It is overly verbose for the task at hand. It requires specifying the type 
>>> of property that the variable is effectively acting as an alias for, 
>>> stating the property name twice, and also doesn’t preclude the possibility 
>>> of mistakenly using `privateBar.baz = foo` in the setter, which looks 
>>> correct at a glance but just assigns the existing value of `baz` back to 
>>> it, effectively doing nothing.
>>> 
>>> It could potentially be shortened, as follows:
>>> 
>>> public alias var foo = privateBar.baz
>>> 
>>> This new syntax omits additional type information which could be inferred 
>>> from the type of the original variable, prevents any assignment mistakes in 
>>> the setter, reduces the number of lines of code needed, and makes it clear 
>>> that the purpose of the variable is simply to act as an alias.
>>> 
>>> I have used the `alias` keyword above as a placeholder. I suppose there 
>>> might be needed some way to clarify that `foo` is still a computed 
>>> property, and not a stored property declared as having the value of 
>>> `privateBar.baz`. I realise that introducing a new keyword is not a trivial 
>>> change, however this was simply the best idea I could come up with; I’m 
>>> sure the community can find better solutions.
>>> 
>>> At the same time, a new keyword makes the intention of the variable 
>>> explicit, and would break no Swift 3.* code.
>>> 
>>> I realise this is just syntactic sugar, however the pattern is common 
>>> enough that I feel like it merits some discussion.
>> 
>> It's reasonable to ask for sugar when a common pattern is unusually verbose, 
>> but I'd like to explore if that's really the case here.
>> 
>> I've had occasion to use a public computed property which returns a private 
>> stored property, but it's _never_ been only that. There's usually some 
>> tricky validation going on or something else that prevents me from just 
>> making the private property `public` or `public internal(set)`. It seems 
>> you're showing one such case where the stored property is in fact stored in 
>> some other variable of a different type. Is it actually very common? In what 
>> sort of programming?
> 
> I’ve used this pattern on occasion to expose properties of value types to KVO:
> 
> class SomeObservableThing: NSObject {
>   var someValueType: SomeValueType {
>   willSet {
>   self.willChangeValue(forKey: #keyPath(foo))
>   self.willChangeValue(forKey: #keyPath(bar))
>   }
>   didSet {
>   self.didChangeValue(forKey: #keyPath(foo))
>   self.didChangeValue(forKey: #keyPath(bar))
>   }
>   }
> 
>   @objc private static let automaticallyNotifiesObserversOfFoo = false
>   @objc var foo: Foo {
>   get { return self.someValueType.foo }
>   set { self.someValueType.foo = newValue }
>   }
> 
>   @objc private static let automaticallyNotifiesObserversOfBar = false
>   @objc var bar: Bar {
>   get { return self.someValueType.bar }
>   set { self.someValueType.bar = newValue }
>   }
> }
> 
> The accessors on foo and bar aren’t really the most obnoxious bits of 
> boilerplate here, though.
> 
> Charles
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Idea: "pure" keyword for function signatures

2017-05-25 Thread Xiaodi Wu via swift-evolution
This is a topic of considerable history. See:

https://lists.swift.org/pipermail/swift-evolution/
Week-of-Mon-20151214/003684.html
https://lists.swift.org/pipermail/swift-evolution/
Week-of-Mon-20151221/003900.html
https://lists.swift.org/pipermail/swift-evolution/
Week-of-Mon-20160104/006005.html
https://lists.swift.org/pipermail/swift-evolution/
Week-of-Mon-20160905/027010.html
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170213/032076.html

It would be important for those who wish to rekindle this discussion first
to review and summarize the preceding, and very technically illuminating,
discussions.


On Thu, May 25, 2017 at 5:39 PM, Michael Savich via swift-evolution <
swift-evolution@swift.org> wrote:

> Writing functions without side effects is generally considered to result
> in less error-prone code. In Swift today, if you want to segment your code
> into pure and impure functions, you just have to police yourself, which is
> a very un-Swifty thing to have to do. This problem is compounded when
> working in teams, where someone else of course won’t know which of your
> functions are pure, and even if you leave a comment it’s not a guarantee
> they’ll know (or care) what “pure” means.
>
> So what about adding the ability to annotate functions with a special
> keyword? For example "pure func addTwoNums(n1: Int, n2: Int)”.
> The rule here is very simple: functions annotated with “pure” can only
> call other functions annotated with “pure”, otherwise the compiler produces
> an error.
>
> To me, this feels like a very natural fit for Swift. What does everybody
> else 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] Idea: "pure" keyword for function signatures

2017-05-25 Thread Michael Savich via swift-evolution
Writing functions without side effects is generally considered to result in 
less error-prone code. In Swift today, if you want to segment your code into 
pure and impure functions, you just have to police yourself, which is a very 
un-Swifty thing to have to do. This problem is compounded when working in 
teams, where someone else of course won’t know which of your functions are 
pure, and even if you leave a comment it’s not a guarantee they’ll know (or 
care) what “pure” means.

So what about adding the ability to annotate functions with a special keyword? 
For example "pure func addTwoNums(n1: Int, n2: Int)”.
The rule here is very simple: functions annotated with “pure” can only call 
other functions annotated with “pure”, otherwise the compiler produces an error.

To me, this feels like a very natural fit for Swift. What does everybody else 
think?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Revisiting SE-0110

2017-05-25 Thread Anders Ha via swift-evolution
It is also fairly common not only with stdlib collection types, but also async 
programming libraries like RxSwift and ReactiveSwift. Given n discrete time 
sequence with values of type X1, X2, ... and Xn respectively, these may combine 
or zip the sequences into a sequence of value type `(X1, X2, …, Xn)`. Then the 
resulting sequence is observed with a closure `((X1, X2, …, Xn)) -> Void`, 
written as `{ x1, x2, …, xn in arbitraryWork() }`.

This could be a considerable regression for these libraries specifically, since 
Swift doesn’t seem getting variadic generics in the near future. A notable side 
effect would be losing return type inference on all these use cases, since the 
closure is now forced to be multi-line if one wants named tuple members.

> On 25 May 2017, at 11:47 PM, Nate Cook via swift-evolution 
>  wrote:
> 
>> Joe Groff wrote:
>> 
>> Furthermore, this probably comes up most commonly with dictionaries, since 
>> they're a sequence of tuples. The element tuple for dictionaries has element 
>> labels (key: Key, value: Value), so instead of writing `{ tuple in let (key, 
>> value) = tuple; f(key, value) }`, you could use the implicit argument and 
>> write `{ f($0.key, $0.value) }`.
> 
> Dictionaries are definitely a common case for this, but zipped sequences and 
> enumerated() sequences are also very common, and don't have labels attached.
> 
> Closures are so lightweight and permissive in what they accept that this 
> change really does feel like a regression. I don't think the proposal 
> accurately captured the impact of this change on code - that section only 
> says "Minor changes to user code may be required if this proposal is 
> accepted." Moreover, the examples given are all of standalone closures 
> assigned to a constant rather than the far more prevalent inline usage in 
> collection operations.
> 
>> Chris Lattner wrote: 
>> 
>> For consistency, the decision was to make closure parameter lists work the 
>> same way as function parameters. Function parameters do not allow 
>> destructuring of arguments in their declaration, so it seemed weird to let 
>> closures do that.
> 
> I have to say that for me, it has never seemed weird at the use site to 
> destructure tuples like that. The only confusion I've ever seen from users is 
> when deconstruction didn't work enough, like if the parameter was (Int, (Int, 
> Int)) and you couldn't destructure the nested tuple.
> 
> Nate
> ___
> 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] Computed properties as aliases

2017-05-25 Thread Charles Srstka via swift-evolution
> On May 25, 2017, at 1:34 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> On Thu, May 25, 2017 at 10:08 AM, Harshil Shah via swift-evolution 
> > wrote:
> Hi all,
> 
> The idea behind this is to add a shorter, cleaner syntax for the common 
> pattern of using computed properties to provide public API for properties of 
> private variables.
> 
> For example:
> 
> public var foo: Type {
> get { return privateBar.baz }
> set { privateBar.baz = newValue }
> }
> 
> While this is a great improvement over the previous convention of `someVar:` 
> and `setSomeVar:` as found in a lot of UIKit, it still has some issues.
> 
> It is overly verbose for the task at hand. It requires specifying the type of 
> property that the variable is effectively acting as an alias for, stating the 
> property name twice, and also doesn’t preclude the possibility of mistakenly 
> using `privateBar.baz = foo` in the setter, which looks correct at a glance 
> but just assigns the existing value of `baz` back to it, effectively doing 
> nothing.
> 
> It could potentially be shortened, as follows:
> 
> public alias var foo = privateBar.baz
> 
> This new syntax omits additional type information which could be inferred 
> from the type of the original variable, prevents any assignment mistakes in 
> the setter, reduces the number of lines of code needed, and makes it clear 
> that the purpose of the variable is simply to act as an alias.
> 
> I have used the `alias` keyword above as a placeholder. I suppose there might 
> be needed some way to clarify that `foo` is still a computed property, and 
> not a stored property declared as having the value of `privateBar.baz`. I 
> realise that introducing a new keyword is not a trivial change, however this 
> was simply the best idea I could come up with; I’m sure the community can 
> find better solutions.
> 
> At the same time, a new keyword makes the intention of the variable explicit, 
> and would break no Swift 3.* code.
> 
> I realise this is just syntactic sugar, however the pattern is common enough 
> that I feel like it merits some discussion.
> 
> It's reasonable to ask for sugar when a common pattern is unusually verbose, 
> but I'd like to explore if that's really the case here.
> 
> I've had occasion to use a public computed property which returns a private 
> stored property, but it's _never_ been only that. There's usually some tricky 
> validation going on or something else that prevents me from just making the 
> private property `public` or `public internal(set)`. It seems you're showing 
> one such case where the stored property is in fact stored in some other 
> variable of a different type. Is it actually very common? In what sort of 
> programming?

I’ve used this pattern on occasion to expose properties of value types to KVO:

class SomeObservableThing: NSObject {
var someValueType: SomeValueType {
willSet {
self.willChangeValue(forKey: #keyPath(foo))
self.willChangeValue(forKey: #keyPath(bar))
}
didSet {
self.didChangeValue(forKey: #keyPath(foo))
self.didChangeValue(forKey: #keyPath(bar))
}
}

@objc private static let automaticallyNotifiesObserversOfFoo = false
@objc var foo: Foo {
get { return self.someValueType.foo }
set { self.someValueType.foo = newValue }
}

@objc private static let automaticallyNotifiesObserversOfBar = false
@objc var bar: Bar {
get { return self.someValueType.bar }
set { self.someValueType.bar = newValue }
}
}

The accessors on foo and bar aren’t really the most obnoxious bits of 
boilerplate here, though.

Charles

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


Re: [swift-evolution] Revisiting SE-0110

2017-05-25 Thread Mark Lacey via swift-evolution

> On May 25, 2017, at 11:27 AM, John McCall via swift-evolution 
>  wrote:
> 
>> On May 25, 2017, at 2:23 PM, Nevin Brackett-Rozinsky via swift-evolution 
>>  wrote:
>> One possibility is to make parentheses consistently meaningful in closure 
>> argument lists, so that “(a, b)” would exclusively mean “there is one 
>> parameter of tuple-type, which is being destructured”, while “a, b” without 
>> parentheses would exclusively mean “there are two parameters”.
>> 
>> That way you can destructure a tuple parameter if you wish (by using 
>> parentheses) or you can leave the tuple intact (by listing a single 
>> identifier without parentheses).
> 
> The problem with this is that we also need some way to be explicit about the 
> return type, and it would be strange to allow (and require!)
>  { a, b -> Int in }
> when that's not at all a valid way to write a function type

This is allowed today, but I agree it would be very strange to require it. 

We also allow:
  { (a, b: Int) -> Int in } // infer ‘a' from context
and
  { (a, b: () -> Int) -> Int in } // infer ‘a' from context
but these become completely ambiguous if you remove the parens.

> .  Also it would be an enormous source break, even worse than this problem.

Yes.

> That said, I'm quite sympathetic to the idea that directly destructuring 
> tuples in closure parameter lists is too useful to lose, even if it's 
> ambiguous.

I think the right thing to do here is add uniform tuple destructuring in 
functions, but that is clearly out of scope for 4.0.

Reverting SE-0110 is not as simple as reverting a single change. So far I have 
found 19 commits that addressed different aspects moving from the old behavior 
by searching for SE-110 and SE-0110 in commit logs. It is possible there were 
others that did not specifically call out the proposal.

Having said that, we are supposed to support the old behavior for 
"-swift-verison 3", so it may be possible to find the handful of places where 
the version check can be removed and old behavior restored under "-swift-verson 
4" if we choose to do that as mitigation until the destructuring feature is 
properly designed and implemented.

Another option is attempting to do some targeted fix specifically for closure 
arguments but that does not seem straightforward, and does seem relatively 
risky.

Mark


> 
> John.
> ___
> 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] Revisiting SE-0110

2017-05-25 Thread Xiaodi Wu via swift-evolution
On Thu, May 25, 2017 at 1:27 PM, John McCall via swift-evolution <
swift-evolution@swift.org> wrote:

> > On May 25, 2017, at 2:23 PM, Nevin Brackett-Rozinsky via swift-evolution
>  wrote:
> > One possibility is to make parentheses consistently meaningful in
> closure argument lists, so that “(a, b)” would exclusively mean “there is
> one parameter of tuple-type, which is being destructured”, while “a, b”
> without parentheses would exclusively mean “there are two parameters”.
> >
> > That way you can destructure a tuple parameter if you wish (by using
> parentheses) or you can leave the tuple intact (by listing a single
> identifier without parentheses).
>
> The problem with this is that we also need some way to be explicit about
> the return type, and it would be strange to allow (and require!)
>   { a, b -> Int in }
> when that's not at all a valid way to write a function type.  Also it
> would be an enormous source break, even worse than this problem.
>
> That said, I'm quite sympathetic to the idea that directly destructuring
> tuples in closure parameter lists is too useful to lose, even if it's
> ambiguous.
>

The option of using the keyword let to disambiguate, proposed somewhere
above or on GitHub, is attractive here:

{ (a, b) -> Int in } // two parameters
{ let (a, b) -> Int in } // destructuring one parameter

{ a, let (b, c) -> Int in } // destructuring two parameters
{ let a, (b, c) -> Int in } // still destructuring two parameters
{ let (a, (b, c)) -> Int in } // destructuring one parameter
{ (a, (b, c)) -> Int in } // error: add 'let' to destructure second
parameter
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Computed properties as aliases

2017-05-25 Thread Xiaodi Wu via swift-evolution
On Thu, May 25, 2017 at 10:08 AM, Harshil Shah via swift-evolution <
swift-evolution@swift.org> wrote:

> Hi all,
>
> The idea behind this is to add a shorter, cleaner syntax for the common
> pattern of using computed properties to provide public API for properties
> of private variables.
>
> For example:
>
> public var foo: Type {
> get { return privateBar.baz }
> set { privateBar.baz = newValue }
> }
>
> While this is a great improvement over the previous convention of
> `someVar:` and `setSomeVar:` as found in a lot of UIKit, it still has some
> issues.
>
> It is overly verbose for the task at hand. It requires specifying the type
> of property that the variable is effectively acting as an alias for,
> stating the property name twice, and also doesn’t preclude the possibility
> of mistakenly using `privateBar.baz = foo` in the setter, which looks
> correct at a glance but just assigns the existing value of `baz` back to
> it, effectively doing nothing.
>
> It could potentially be shortened, as follows:
>
> public alias var foo = privateBar.baz
>
> This new syntax omits additional type information which could be inferred
> from the type of the original variable, prevents any assignment mistakes in
> the setter, reduces the number of lines of code needed, and makes it clear
> that the purpose of the variable is simply to act as an alias.
>
> I have used the `alias` keyword above as a placeholder. I suppose there
> might be needed some way to clarify that `foo` is still a computed
> property, and not a stored property declared as having the value of
> `privateBar.baz`. I realise that introducing a new keyword is not a trivial
> change, however this was simply the best idea I could come up with; I’m
> sure the community can find better solutions.
>
> At the same time, a new keyword makes the intention of the variable
> explicit, and would break no Swift 3.* code.
>
> I realise this is just syntactic sugar, however the pattern is common
> enough that I feel like it merits some discussion.
>

It's reasonable to ask for sugar when a common pattern is unusually
verbose, but I'd like to explore if that's really the case here.

I've had occasion to use a public computed property which returns a private
stored property, but it's _never_ been only that. There's usually some
tricky validation going on or something else that prevents me from just
making the private property `public` or `public internal(set)`. It seems
you're showing one such case where the stored property is in fact stored in
some other variable of a different type. Is it actually very common? In
what sort of programming?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Revisiting SE-0110

2017-05-25 Thread John McCall via swift-evolution
> On May 25, 2017, at 2:23 PM, Nevin Brackett-Rozinsky via swift-evolution 
>  wrote:
> One possibility is to make parentheses consistently meaningful in closure 
> argument lists, so that “(a, b)” would exclusively mean “there is one 
> parameter of tuple-type, which is being destructured”, while “a, b” without 
> parentheses would exclusively mean “there are two parameters”.
> 
> That way you can destructure a tuple parameter if you wish (by using 
> parentheses) or you can leave the tuple intact (by listing a single 
> identifier without parentheses).

The problem with this is that we also need some way to be explicit about the 
return type, and it would be strange to allow (and require!)
  { a, b -> Int in }
when that's not at all a valid way to write a function type.  Also it would be 
an enormous source break, even worse than this problem.

That said, I'm quite sympathetic to the idea that directly destructuring tuples 
in closure parameter lists is too useful to lose, even if it's ambiguous.

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


Re: [swift-evolution] Revisiting SE-0110

2017-05-25 Thread Nevin Brackett-Rozinsky via swift-evolution
One possibility is to make parentheses consistently meaningful in closure
argument lists, so that “(a, b)” would exclusively mean “there is one
parameter of tuple-type, which is being destructured”, while “a, b” without
parentheses would exclusively mean “there are two parameters”.

That way you can destructure a tuple parameter if you wish (by using
parentheses) or you can leave the tuple intact (by listing a single
identifier without parentheses).

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


Re: [swift-evolution] Revisiting SE-0110

2017-05-25 Thread Amit Jain via swift-evolution
In addition to dictionaries, In paradigms like Rx, this sugar helps immensely 
towards writing concise single-line transforms where one can quickly understand 
what the transform is trying to achieve. It is quite common to work with many 
arguments which are morphed as one moves down the chain. Adding boilerplate to 
every single closure in such places will be really noisy and regressive to 
clarity at the point of use. 

> > On May 24, 2017, at 6:18 PM, Ben Cohen via 
> > swift-evolutionwrote:
> > 
> > I very much agree with your concerns about this change in general.
> > 
> > On this specific example, though, I just wanted to point out that there 
> > doesn’t seem to be a good reason to use .forEach here.
> > 
> > for (key, value) in self {
> > // etc
> > }
> > 
> > Would work perfectly well and is clearer IMO, still works with destructing, 
> > doesn’t have gotcha problems related to continue/break not doing what you 
> > might expect, etc.
> > 
> > forEach is only really a win when used on the end of a chain of 
> > map/filter-like operations, where for…in would involve bouncing back from 
> > right to left.
> Furthermore, this probably comes up most commonly with dictionaries, since 
> they're a sequence of tuples. The element tuple for dictionaries has element 
> labels (key: Key, value: Value), so instead of writing `{ tuple in let (key, 
> value) = tuple; f(key, value) }`, you could use the implicit argument and 
> write `{ f($0.key, $0.value) }`.
> 
> -Joe
> 
> 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Revisiting SE-0110

2017-05-25 Thread Gwendal Roué via swift-evolution

> Le 25 mai 2017 à 17:47, Nate Cook via swift-evolution 
>  a écrit :
> 
>> For consistency, the decision was to make closure parameter lists work the 
>> same way as function parameters. Function parameters do not allow 
>> destructuring of arguments in their declaration, so it seemed weird to let 
>> closures do that.
> 
> I have to say that for me, it has never seemed weird at the use site to 
> destructure tuples like that. The only confusion I've ever seen from users is 
> when deconstruction didn't work enough, like if the parameter was (Int, (Int, 
> Int)) and you couldn't destructure the nested tuple.

I even suggest that tuple destructuring gets more consideration.

That is because without restructuring, many closures that could be written as a 
single line have to be written with several lines (in order to explicitly 
destructure input tuples, as in the sample code provided by the OP):

+self.forEach { (arg) in
+let (keyItem, valueItem) = arg

Unfortunately, multiline closures are less nice than single line closures: 
multiline closures can't avoid the `return` keyword. And multiline closures 
have downgraded type inference:

func f(_ closure: () -> T) -> T { return closure() }

// Yeah!
f { 1 }

// Meh: unable to infer complex closure return type; add explicit type to 
disambiguate
f {
let x = 1
return x
}

Of course, the type inference problem above could be fixed independently of 
tuple destructuring. But it looks like it is difficult to implement: see Jordan 
Rose's comment in https://bugs.swift.org/browse/SR-1570 
 which links to 
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/002583.html
 
.

Gwendal Roué

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


Re: [swift-evolution] Pitch: Allow generic functions to fulfill non-generic protocol requirements

2017-05-25 Thread Jordan Rose via swift-evolution
We just don’t allow any broader acceptance in this case—no superclasses, no 
optionals, and no generics. I think we just consider it a bug (SR-522 
).

Jordan


> On May 24, 2017, at 13:32, David Sweeris via swift-evolution 
>  wrote:
> 
> So, I’m working on a type, and would like to make it conform to 
> `ExpressibleByArrayLiteral`. The thing is, I don’t actually care what type 
> `Element` is as long as it conforms to `FixedWidthInteger` and 
> `UnsignedInteger`. I tried writing this:
>   public init  (arrayLiteral 
> elements: U...) { … }
> But Xcode says my type doesn’t conform to `ExpressibleByArrayLiteral` unless 
> I add an init that takes a concrete type:
>   public init(arrayLiteral elements: UInt...) { … }
> 
> Does anyone else think the generic init should to be able to satisfy 
> `ExpressibleByArrayLiteral` (especially since `UInt` meets the conformance 
> requirements)? I suspect that the compiler is complaining because the generic 
> init function implies that the `Element` associated type is a generic 
> constraint, rather than a concrete type (which maybe makes this related to 
> generic protocols?). I think that’s only an issue because of the current 
> ExpressibleBy*Literal protocols’ reliance on associated types to specify the 
> relevant init’s signature, though. If the protocols (or literal system) could 
> be re-architected so they don't need those associated types, it might make 
> implementing this easier. I don’t know how much work either approach would 
> be. Nor am I sure if it’d be better for this to be a use-case for another 
> proposal instead of its own thing.
> 
> - 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


Re: [swift-evolution] Revisiting SE-0110

2017-05-25 Thread Nate Cook via swift-evolution
> Joe Groff wrote:
> 
> Furthermore, this probably comes up most commonly with dictionaries, since 
> they're a sequence of tuples. The element tuple for dictionaries has element 
> labels (key: Key, value: Value), so instead of writing `{ tuple in let (key, 
> value) = tuple; f(key, value) }`, you could use the implicit argument and 
> write `{ f($0.key, $0.value) }`.

Dictionaries are definitely a common case for this, but zipped sequences and 
enumerated() sequences are also very common, and don't have labels attached.

Closures are so lightweight and permissive in what they accept that this change 
really does feel like a regression. I don't think the proposal accurately 
captured the impact of this change on code - that section only says "Minor 
changes to user code may be required if this proposal is accepted." Moreover, 
the examples given are all of standalone closures assigned to a constant rather 
than the far more prevalent inline usage in collection operations.

> Chris Lattner wrote: 
> 

> For consistency, the decision was to make closure parameter lists work the 
> same way as function parameters. Function parameters do not allow 
> destructuring of arguments in their declaration, so it seemed weird to let 
> closures do that.

I have to say that for me, it has never seemed weird at the use site to 
destructure tuples like that. The only confusion I've ever seen from users is 
when deconstruction didn't work enough, like if the parameter was (Int, (Int, 
Int)) and you couldn't destructure the nested tuple.

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


[swift-evolution] [Pitch] Computed properties as aliases

2017-05-25 Thread Harshil Shah via swift-evolution
Hi all,

The idea behind this is to add a shorter, cleaner syntax for the common pattern 
of using computed properties to provide public API for properties of private 
variables.

For example:

public var foo: Type {
get { return privateBar.baz }
set { privateBar.baz = newValue }
}

While this is a great improvement over the previous convention of `someVar:` 
and `setSomeVar:` as found in a lot of UIKit, it still has some issues.

It is overly verbose for the task at hand. It requires specifying the type of 
property that the variable is effectively acting as an alias for, stating the 
property name twice, and also doesn’t preclude the possibility of mistakenly 
using `privateBar.baz = foo` in the setter, which looks correct at a glance but 
just assigns the existing value of `baz` back to it, effectively doing nothing.

It could potentially be shortened, as follows:

public alias var foo = privateBar.baz

This new syntax omits additional type information which could be inferred from 
the type of the original variable, prevents any assignment mistakes in the 
setter, reduces the number of lines of code needed, and makes it clear that the 
purpose of the variable is simply to act as an alias.

I have used the `alias` keyword above as a placeholder. I suppose there might 
be needed some way to clarify that `foo` is still a computed property, and not 
a stored property declared as having the value of `privateBar.baz`. I realise 
that introducing a new keyword is not a trivial change, however this was simply 
the best idea I could come up with; I’m sure the community can find better 
solutions.

At the same time, a new keyword makes the intention of the variable explicit, 
and would break no Swift 3.* code.

I realise this is just syntactic sugar, however the pattern is common enough 
that I feel like it merits some discussion.

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


Re: [swift-evolution] Revisiting SE-0110

2017-05-25 Thread Joe Groff via swift-evolution

> On May 24, 2017, at 6:18 PM, Ben Cohen via swift-evolution 
>  wrote:
> 
> I very much agree with your concerns about this change in general.
> 
> On this specific example, though, I just wanted to point out that there 
> doesn’t seem to be a good reason to use .forEach here.
> 
> for (key, value) in self {
>   // etc
> }
> 
> Would work perfectly well and is clearer IMO, still works with destructing, 
> doesn’t have gotcha problems related to continue/break not doing what you 
> might expect, etc. 
> 
> forEach is only really a win when used on the end of a chain of 
> map/filter-like operations, where for…in would involve bouncing back from 
> right to left.

Furthermore, this probably comes up most commonly with dictionaries, since 
they're a sequence of tuples. The element tuple for dictionaries has element 
labels (key: Key, value: Value), so instead of writing `{ tuple in let (key, 
value) = tuple; f(key, value) }`, you could use the implicit argument and write 
`{ f($0.key, $0.value) }`.

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


Re: [swift-evolution] Revisiting SE-0110

2017-05-25 Thread gs. via swift-evolution
I wish that we had gone in the other direction and let functions allow 
destructuring of parameters. That said, I guess I can see how that chance left 
when we decided to move away from function parameters as tuples.

TJ 

> On May 25, 2017, at 02:08, Chris Lattner via swift-evolution 
>  wrote:
> 
> 
>> On May 24, 2017, at 12:12 PM, Tony Parker via swift-evolution 
>>  wrote:
>> 
>> Hi everyone,
>> 
>> We received a pull request in swift-corelibs-foundation which is apparently 
>> in response to a language change for SE-0110.
>> 
>> It turns this perfectly reasonable code:
>> 
>> -self.forEach { (keyItem, valueItem) in
>> 
>> into this:
>> 
>> 
>> +self.forEach { (arg) in
>> +let (keyItem, valueItem) = arg
>> 
>> Is that really the design pattern we want to encourage? What was wrong with 
>> the previous code?
> 
> For consistency, the decision was to make closure parameter lists work the 
> same way as function parameters.  Function parameters do not allow 
> destructuring of arguments in their declaration, so it seemed weird to let 
> closures do that.
> 
> Similarly, this doesn’t compile either:
> 
>   self.ForEach(functionTakingTwoParameters)
> 
> even if the two parameters are equivalent to the element type of the self 
> Sequence
> 
> -Chris
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Revisiting SE-0110

2017-05-25 Thread Chris Lattner via swift-evolution

> On May 24, 2017, at 12:12 PM, Tony Parker via swift-evolution 
>  wrote:
> 
> Hi everyone,
> 
> We received a pull request in swift-corelibs-foundation which is apparently 
> in response to a language change for SE-0110.
> 
> It turns this perfectly reasonable code:
> 
> -self.forEach { (keyItem, valueItem) in
> 
> into this:
> 
> 
> +self.forEach { (arg) in
> +let (keyItem, valueItem) = arg
> 
> Is that really the design pattern we want to encourage? What was wrong with 
> the previous code?

For consistency, the decision was to make closure parameter lists work the same 
way as function parameters.  Function parameters do not allow destructuring of 
arguments in their declaration, so it seemed weird to let closures do that.

Similarly, this doesn’t compile either:

self.ForEach(functionTakingTwoParameters)

even if the two parameters are equivalent to the element type of the self 
Sequence

-Chris


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