Re: [swift-evolution] [Pitch] Improve `init(repeating:count)`

2017-08-17 Thread Rintaro Ishizaki via swift-evolution
I don't think it's worthwhile adding new API.
I think this is simple enough:

let views = Array(AnyIterator(UIView.init).prefix(3))

2017-08-17 21:04 GMT+09:00 Robert Bennett via swift-evolution <
swift-evolution@swift.org>:

> Alternatively, instead of replacing the current definition with an
> autoclosure version, we could leave the current version in place and add a
> version taking a function. This could be especially useful when you’ve
> defined a function like `makeMySpecialKindOfButton() -> UIButton` that does
> a lot of customization to an object before returning it.
>
> Array(repeating: { return UIView() }, count: 3)
> and
> Array(repeating: makeMySpecialKindOfButton, count: 3)
>
> On Aug 17, 2017, at 7:54 AM, Haravikk via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> On 17 Aug 2017, at 10:38, Adrian Zubarev via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> This is a small pitch which I will abandon if there is not much appetite
> for such improvement. ;)
>
> I would like to propose an improvement to an initializer of all collection
> types that provide: init(repeating repeatedValue: Element, count: Int).
>
> This change is meant to support reference type initialization on each
> iteration of the internal for-loop rather than copying the same references
> n times.
>
> The change would be really straightforward and should not break existing
> code, except that the behavior would change for class types.
>
> Instead of:
>
> init(repeating repeatedValue: Element, count: Int)
>
> let threeViews = Array(repeating: UIView(), count: 3) // contains 1 view 3 
> times
>
> we would have:
>
> init(repeating repeatedValue: @autoclosure () -> Element, count: Int)
>
> This simple change would allow us to construct an array of different
> objects instead of an array with n references to the same object.
>
> let threeViews = Array(repeating: UIView(), count: 3) // contains 3 different 
> view
>
> I don't think that changing the existing initialiser is the way to do
> this, as it's not really clear here that the UIView() will be instantiated
> multiple times rather than the same reference copied multiple times. The
> copying behaviour is in fact desirable as it will be significantly faster,
> especially with very large arrays.
>
> I think the better way to achieve this might be add some closure-based
> sequence that returns a closure's result N times, so we could do something
> like this:
>
> let threeViews = Array(Repeat(count: 3) { return UIView() })
>
> i.e- we would initialise Array from a sequence returning a new UIView
> three times. While we could also do an array initialiser with closure,
> using a separate type is probably the cleaner way to do this.
>
> There is already a Repeater type, but this just does the same as the array
> initialiser already does, could be another type I've missed that might do
> what is needed, otherwise it seems to require types like AnyIterator with
> some counting 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
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Scoped @available

2017-07-10 Thread rintaro ishizaki via swift-evolution
2017-07-10 14:05 GMT+09:00 Xiaodi Wu :

> This would be very useful, but the spelling needs dramatic improvement.
>
> "Available unavailable" is already challenging to read, but at least it is
> learnable with time. The example where "@available(*, deprecated, access:
> internal) open" means "fileprivate" is entirely unreasonable.
>
>
I agree, but I couldn't come up with a better spelling.

// "deprecated" if the access is from "outside" of "fileprivate" scope.
@available(*, deprecated, outside: fileprivate) open

Hmm.. 🤔

Any suggestions will be greatly appreciated!



> On Sun, Jul 9, 2017 at 22:40 rintaro ishizaki via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> Hi evolution community,
>>
>> I would like to propose "Scoped @available" attribute.
>>
>> What I want to achieve is to declare something that is publicly
>> unavailable, but still usable from narrower scope. A concrete example is
>> IndexableBase in the standard library:
>> https://github.com/apple/swift/blob/master/stdlib/public/cor
>> e/Collection.swift#L18-L20
>> Workaround for this problem in stdlib is to use typealias to underscored
>> declaration. However, we can't use this technique in our module because
>> underscored declarations are still visible and usable from outside.
>>
>> As a solution, I propose to add "access" parameter to @available
>> attribute, which limits the effect of @available attribute to the
>> specified value or outer.
>>
>> ---
>> // Module: Library
>>
>> /// This protocol is available for internal, but deprecated for public.
>> @available(*, deprecated, access: public, message: "it will be removed in
>> future")
>> public protocol OldProtocol {
>> /* ... */
>> }
>>
>> public Foo: OldProtocol { // No diagnostics
>> }
>>
>> ---
>> // Module: main
>>
>> import Library
>>
>> public Bar: OldProtocol { // warning: 'OldProtocol' is deprecated: it
>> will be removed in future
>> }
>>
>> ---
>>
>> I think this is useful when you want to stop exposing declarations, but
>> want to keep using them internally.
>>
>> More examples:
>>
>> // is `open`, going to be `filerprivate`
>> @available(*, deprecated, access: internal)
>> open class Foo {}
>>
>> // was `internal`, now `private`
>> @available(*, unavailable, access: fileprivate)
>> var value: Int
>>
>> // No effect (invisible from public anyway): emit a warning
>> @available(*, unavailable, access: public)
>> internal struct Foo {}
>>
>> 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] [Pitch] Scoped @available

2017-07-09 Thread rintaro ishizaki via swift-evolution
Hi evolution community,

I would like to propose "Scoped @available" attribute.

What I want to achieve is to declare something that is publicly
unavailable, but still usable from narrower scope. A concrete example is
IndexableBase in the standard library:
https://github.com/apple/swift/blob/master/stdlib/
public/core/Collection.swift#L18-L20
Workaround for this problem in stdlib is to use typealias to underscored
declaration. However, we can't use this technique in our module because
underscored declarations are still visible and usable from outside.

As a solution, I propose to add "access" parameter to @available attribute,
which limits the effect of @available attribute to the specified value or
outer.

---
// Module: Library

/// This protocol is available for internal, but deprecated for public.
@available(*, deprecated, access: public, message: "it will be removed in
future")
public protocol OldProtocol {
/* ... */
}

public Foo: OldProtocol { // No diagnostics
}

---
// Module: main

import Library

public Bar: OldProtocol { // warning: 'OldProtocol' is deprecated: it will
be removed in future
}

---

I think this is useful when you want to stop exposing declarations, but
want to keep using them internally.

More examples:

// is `open`, going to be `filerprivate`
@available(*, deprecated, access: internal)
open class Foo {}

// was `internal`, now `private`
@available(*, unavailable, access: fileprivate)
var value: Int

// No effect (invisible from public anyway): emit a warning
@available(*, unavailable, access: public)
internal struct Foo {}

What do you think?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Contextual variables

2017-07-02 Thread rintaro ishizaki via swift-evolution
Ughh, my bad, let me withdraw this idea:

func saveAndRestore(_ variable: inout T, _ tmpVal: T, body: ()
-> R) -> R {
let savedVal = variable
variable = tmpVal
defer { variable = savedVal }
return body()
}
var contextVal: Int = 0saveAndRestore(&contextVal, 1) {
print(contextVal)
}


I don't think this is guaranteed to work.




2017-07-03 11:48 GMT+09:00 rintaro ishizaki via swift-evolution <
swift-evolution@swift.org>:

>
>
> 2017-07-03 11:23 GMT+09:00 rintaro ishizaki via swift-evolution <
> swift-evolution@swift.org>:
>
>>
>>
>> 2017-06-28 21:33 GMT+09:00 Dimitri Racordon via swift-evolution <
>> swift-evolution@swift.org>:
>>
>>> Hello community!
>>>
>>> I’d like to pitch an idea for a user-friendly way for functions to pull
>>> values from an arbitrary environment. Let me introduce the concept with a
>>> motivational example before I dig into dirty syntax and semantics. Note
>>> that I intentionally removed many pieces of code from my examples, but I
>>> guess everybody will be able to understand the context.
>>>
>>> Say you are writing a visitor (with the pattern of the same name) for an
>>> AST to implement an interpreter:
>>>
>>> class Interpreter: Visitor {
>>> func visit(_ node: BinExpr){ /* ... */ }
>>> func visit(_ node: Literal){ /* ... */ }
>>> func visit(_ node: Scope)  { /* ... */ }
>>> func visit(_ node: Identifier) { /* ... */ }
>>> }
>>>
>>> Although this design pattern is often recommended for AST processing,
>>> managing data as we go down the tree can be cumbersome. The problem is that
>>> we need to store all intermediate results as we climb up the tree in some
>>> instance member, because we can’t use the return type of the visit(_:) 
>>> method,
>>> as we would do with a recursive function:
>>>
>>
>>
>> Why you can't use the return type? associatedtype doesn't solve the
>> problem?
>>
>> protocol Visitor {
>> associatedtype VisitResult
>> func visit(_ node: BinExpr) throws -> VisitResult
>> func visit(_ node: Literal) throws -> VisitResult
>> func visit(_ node: Scope) throws -> VisitResult
>> func visit(_ node: Identifier) throws -> VisitResult
>> }
>> extension BinExpr {
>> func accept(_ visitor: V) throws -> V.VisitResult { return 
>> visitor.visit(self) }
>> }extension Literal {
>> func accept(_ visitor: V) throws -> V.VisitResult { return 
>> visitor.visit(self) }
>> }extension Scope {
>> func accept(_ visitor: V) throws -> V.VisitResult { return 
>> visitor.visit(self) }
>> }extension Identifier {
>> func accept(_ visitor: V) throws -> V.VisitResult { return 
>> visitor.visit(self) }
>> }
>> class Interpreter : Visitor {
>> func visit(_ node: BinExpr) -> Int {
>> let lhsResult = node.lhs.accept(self)
>> let rhsResult = node.rhs.accept(self)
>> /* ... */
>> return result
>> }
>>
>> /* ... */
>> }
>>
>>
>>
>>
>>
>>
>>> class Interpreter: Visitor {
>>> func visit(_ node: BinExpr) {
>>> node.lhs.accept(self)
>>> let lhs = accumulator!
>>> node.rhs.accept(self)
>>> let rhs = accumulator!
>>> /* ... */
>>> }
>>>
>>> func visit(_ node: Literal){ /* ... */ }
>>> func visit(_ node: Scope)  { /* ... */ }
>>> func visit(_ node: Identifier) { /* ... */ }
>>>
>>> var accumulator: Int? = nil
>>>
>>> /* ... */
>>> }
>>>
>>> As our interpreter will grow and need more visitors to “return” a value,
>>> we’ll be forced to add more and more stored properties to its definition.
>>> Besides, the state of those properties is difficult to debug, as it can
>>> quickly become unclear what depth of the tree they should be associated to.
>>> In fact, it is as if all these properties acted as global variables.
>>>
>>> The problem gets even bigger when we need to *pass* variables to a
>>> particular execution of a visit(_:). Not only do we need to add a
>>> stored property to represent each “argument”, but we also have to store
>>> them in stacks so that a nested calls to a particular visit can get their
>>> own “evaluation context”. Consider for instance the implementation

Re: [swift-evolution] [Pitch] Contextual variables

2017-07-02 Thread rintaro ishizaki via swift-evolution
2017-07-03 11:23 GMT+09:00 rintaro ishizaki via swift-evolution <
swift-evolution@swift.org>:

>
>
> 2017-06-28 21:33 GMT+09:00 Dimitri Racordon via swift-evolution <
> swift-evolution@swift.org>:
>
>> Hello community!
>>
>> I’d like to pitch an idea for a user-friendly way for functions to pull
>> values from an arbitrary environment. Let me introduce the concept with a
>> motivational example before I dig into dirty syntax and semantics. Note
>> that I intentionally removed many pieces of code from my examples, but I
>> guess everybody will be able to understand the context.
>>
>> Say you are writing a visitor (with the pattern of the same name) for an
>> AST to implement an interpreter:
>>
>> class Interpreter: Visitor {
>> func visit(_ node: BinExpr){ /* ... */ }
>> func visit(_ node: Literal){ /* ... */ }
>> func visit(_ node: Scope)  { /* ... */ }
>> func visit(_ node: Identifier) { /* ... */ }
>> }
>>
>> Although this design pattern is often recommended for AST processing,
>> managing data as we go down the tree can be cumbersome. The problem is that
>> we need to store all intermediate results as we climb up the tree in some
>> instance member, because we can’t use the return type of the visit(_:) 
>> method,
>> as we would do with a recursive function:
>>
>
>
> Why you can't use the return type? associatedtype doesn't solve the
> problem?
>
> protocol Visitor {
> associatedtype VisitResult
> func visit(_ node: BinExpr) throws -> VisitResult
> func visit(_ node: Literal) throws -> VisitResult
> func visit(_ node: Scope) throws -> VisitResult
> func visit(_ node: Identifier) throws -> VisitResult
> }
> extension BinExpr {
> func accept(_ visitor: V) throws -> V.VisitResult { return 
> visitor.visit(self) }
> }extension Literal {
> func accept(_ visitor: V) throws -> V.VisitResult { return 
> visitor.visit(self) }
> }extension Scope {
> func accept(_ visitor: V) throws -> V.VisitResult { return 
> visitor.visit(self) }
> }extension Identifier {
> func accept(_ visitor: V) throws -> V.VisitResult { return 
> visitor.visit(self) }
> }
> class Interpreter : Visitor {
> func visit(_ node: BinExpr) -> Int {
> let lhsResult = node.lhs.accept(self)
> let rhsResult = node.rhs.accept(self)
> /* ... */
> return result
> }
>
> /* ... */
> }
>
>
>
>
>
>
>> class Interpreter: Visitor {
>> func visit(_ node: BinExpr) {
>> node.lhs.accept(self)
>> let lhs = accumulator!
>> node.rhs.accept(self)
>> let rhs = accumulator!
>> /* ... */
>> }
>>
>> func visit(_ node: Literal){ /* ... */ }
>> func visit(_ node: Scope)  { /* ... */ }
>> func visit(_ node: Identifier) { /* ... */ }
>>
>> var accumulator: Int? = nil
>>
>> /* ... */
>> }
>>
>> As our interpreter will grow and need more visitors to “return” a value,
>> we’ll be forced to add more and more stored properties to its definition.
>> Besides, the state of those properties is difficult to debug, as it can
>> quickly become unclear what depth of the tree they should be associated to.
>> In fact, it is as if all these properties acted as global variables.
>>
>> The problem gets even bigger when we need to *pass* variables to a
>> particular execution of a visit(_:). Not only do we need to add a stored
>> property to represent each “argument”, but we also have to store them in
>> stacks so that a nested calls to a particular visit can get their own
>> “evaluation context”. Consider for instance the implementation of the
>> visit(_ node: Identifier), assuming that the language our AST represents
>> would support lexical scoping.
>>
>
>
> How about returning curried function from visitor?
>
>
> class Interpreter : Visitor {
>
> typealias VisitResult = ([String:Int]) throws -> Int
>
> func visit(_ node: Identifier) throws -> VisitResult {
> return { symbols in
> guard let result = symbols[node.name] {
> throws UndefinedIdentifierError(node.name)
> }
> return result
> }
> }
>
> /* ... */
> }
>
>
>
>
>> class Interpreter: Visitor {
>> /* ... */
>>
>> func visit(_ node: Scope) {
>> symbols.append([:])
>> for child in node.children {
>> child.ac

Re: [swift-evolution] [Pitch] Contextual variables

2017-07-02 Thread rintaro ishizaki via swift-evolution
2017-06-28 21:33 GMT+09:00 Dimitri Racordon via swift-evolution <
swift-evolution@swift.org>:

> Hello community!
>
> I’d like to pitch an idea for a user-friendly way for functions to pull
> values from an arbitrary environment. Let me introduce the concept with a
> motivational example before I dig into dirty syntax and semantics. Note
> that I intentionally removed many pieces of code from my examples, but I
> guess everybody will be able to understand the context.
>
> Say you are writing a visitor (with the pattern of the same name) for an
> AST to implement an interpreter:
>
> class Interpreter: Visitor {
> func visit(_ node: BinExpr){ /* ... */ }
> func visit(_ node: Literal){ /* ... */ }
> func visit(_ node: Scope)  { /* ... */ }
> func visit(_ node: Identifier) { /* ... */ }
> }
>
> Although this design pattern is often recommended for AST processing,
> managing data as we go down the tree can be cumbersome. The problem is that
> we need to store all intermediate results as we climb up the tree in some
> instance member, because we can’t use the return type of the visit(_:) method,
> as we would do with a recursive function:
>


Why you can't use the return type? associatedtype doesn't solve the problem?

protocol Visitor {
associatedtype VisitResult
func visit(_ node: BinExpr) throws -> VisitResult
func visit(_ node: Literal) throws -> VisitResult
func visit(_ node: Scope) throws -> VisitResult
func visit(_ node: Identifier) throws -> VisitResult
}
extension BinExpr {
func accept(_ visitor: V) throws -> V.VisitResult {
return visitor.visit(self) }
}extension Literal {
func accept(_ visitor: V) throws -> V.VisitResult {
return visitor.visit(self) }
}extension Scope {
func accept(_ visitor: V) throws -> V.VisitResult {
return visitor.visit(self) }
}extension Identifier {
func accept(_ visitor: V) throws -> V.VisitResult {
return visitor.visit(self) }
}
class Interpreter : Visitor {
func visit(_ node: BinExpr) -> Int {
let lhsResult = node.lhs.accept(self)
let rhsResult = node.rhs.accept(self)
/* ... */
return result
}

/* ... */
}






> class Interpreter: Visitor {
> func visit(_ node: BinExpr) {
> node.lhs.accept(self)
> let lhs = accumulator!
> node.rhs.accept(self)
> let rhs = accumulator!
> /* ... */
> }
>
> func visit(_ node: Literal){ /* ... */ }
> func visit(_ node: Scope)  { /* ... */ }
> func visit(_ node: Identifier) { /* ... */ }
>
> var accumulator: Int? = nil
>
> /* ... */
> }
>
> As our interpreter will grow and need more visitors to “return” a value,
> we’ll be forced to add more and more stored properties to its definition.
> Besides, the state of those properties is difficult to debug, as it can
> quickly become unclear what depth of the tree they should be associated to.
> In fact, it is as if all these properties acted as global variables.
>
> The problem gets even bigger when we need to *pass* variables to a
> particular execution of a visit(_:). Not only do we need to add a stored
> property to represent each “argument”, but we also have to store them in
> stacks so that a nested calls to a particular visit can get their own
> “evaluation context”. Consider for instance the implementation of the
> visit(_ node: Identifier), assuming that the language our AST represents
> would support lexical scoping.
>


How about returning curried function from visitor?


class Interpreter : Visitor {

typealias VisitResult = ([String:Int]) throws -> Int

func visit(_ node: Identifier) throws -> VisitResult {
return { symbols in
guard let result = symbols[node.name] {
throws UndefinedIdentifierError(node.name)
}
return result
}
}

/* ... */
}




> class Interpreter: Visitor {
> /* ... */
>
> func visit(_ node: Scope) {
> symbols.append([:])
> for child in node.children {
> child.accept(self)
> }
> symbols.removeLast()
> }
>
> func visit(_ node: Identifier) {
> accumulator = symbols.last![node.name]!
> }
>
> var symbols = [[String: Int]]()
> }
>
> We could instead create another instance of our visitor to set manage
> those evaluation contexts. But that would require us to explicitly copy all
> the variables associated to those contexts, which could potentially be
> inefficient and error prone.
>
> In fact, this last point is also true when dealing with recursive
> functions. For instance, our visit(_ node: Identifier) method could be
> rewritten as:
>
> func interpret(_ identifier: Identifier, symbols: [String: Value]) -> Int
>  { /* ... */ }
>
> so that its evaluation context is passed as a parameter. But this also
> requires all other functions to also pass this argument, even if their
> execution does not require the parameter.
>
> func interpret(_ binExpr: 

Re: [swift-evolution] [pitch] Substring performance affordances

2017-06-28 Thread rintaro ishizaki via swift-evolution
Hi,

Just a quick question. Does this mean it's guaranteed that
Substring.hashValue is always equal to String.hashValue?


```
let foobar: String = "foo bar"
let sliced: Substring = foobar.suffix(3)
let bar = "bar"
bar.hashValue == sliced.hashValue // guaranteed?
```


2017-06-29 1:37 GMT+09:00 Ben Cohen via swift-evolution <
swift-evolution@swift.org>:

> Hi swift-evolution,
>
> Below is a short pitch for some performance improvements to be made to
> String to accommodate Substrings.
>
> As outlined in SE-0163, the more general question of implicit conversion
> from Substring to String was deferred pending feedback on the initial
> implementation. To date, the feedback we’ve received hasn’t suggested that
> such an implicit conversion is necessary – that migrations from 3.2 to 4.0
> haven’t led to an extensive need to perform Substring->String conversion.
> Any further input, either on or off list, about this particular aspect of
> migration would be very gratefully received.
>
> # Substring performance affordances
>
> * Proposal: [SE-](-substring-affordances.md)
> * Authors: [Ben Cohen](https://github.com/airspeedswift)
> * Review Manager: TBD
> * Status: **Awaiting review**
>
> ## Introduction
>
> This proposal modifies a small number of methods in the standard library
> that
> are commonly used with the `Substring` type:
>
> - Modify the `init` on floating point and integer types, to construct them
>   from `StringProtocol` rather than `String`.
> - Change `join` to be an extension `where Element: StringProtocol`
> - Add extensions to `Dictionary where Key == String` and `Set where
> Element ==
>   String` to test for presence of a `Substring`.
>
> ## Motivation
>
> Swift 4 introduced `Substring` as the slice type for `String`. Previously,
> `String` had been its own slice type, but this leads to issues where string
> buffers can be unexpectedly retained. This approach was adopted instead of
> the
> alternative of having the slicing operation make a copy. A copying slicing
> operation would have negative performance consequences, and would also
> conflict
> with the requirement that `Collection` be sliceable in constant time. In
> cases
> where an API requires a `String`, the user must construct a new `String`
> from a
> `Substring`. This can be thought of as a "deferral" of the copy that was
> avoided at the time of the slice.
>
> There are a few places in the standard library where it is notably
> inefficient
> to force a copy of a substring in order to use it with a string: performing
> lookups in hashed containers, joining substrings, and converting
> substrings to
> integers. In particular, these operations are likely to be used inside a
> loop
> over a number of substrings extracted from a string. For example, suppose
> you
> had a string of key/value pairs, where the values were integers and you
> wanted
> to sum them by key. You would be forced to convert both the `Substring`
> keys
> and values to `String` to do this.
>
> ## Proposed solution
>
> Add the following to the standard library:
>
> ```swift
> extension FixedWidthInteger {
>  public init?(_ text: S, radix: Int = 10)
> }
>
> extension Float/Double/Float80 {
>  public init?(_ text: S, radix: Int = 10)
> }
>
> extension Sequence where Element: StringProtocol {
>  public func joined(separator: String = "") -> String
> }
>
> extension Dictionary where Key == String {
>  public subscript(key: Substring) -> Value? { get set }
>  public subscript(key: Substring, default defaultValue: @autoclosure () ->
> Value) -> Value { get set }
> }
>
> extension Set where Element == String {
>  public func contains(_ member: Substring) -> Bool
>  public func index(of member: Substring) -> Index?
>  public mutating func insert(_ newMember: Substring) -> (inserted: Bool,
> memberAfterInsert: Element)
>  public mutating func remove(_ member: Substring) -> Element?
> }
> ```
>
> These additions are deliberately narrow in scope. They are _not_ intended
> to
> solve a general problem of being able to interchange substrings for
> strings (or
> more generally slices for collections) generically in different APIs. See
> the
> alternatives considered section for more on this.
>
> ## Source compatibility
>
> No impact, these are either additive (in case of hashed containers) or
> generalize an existing API to a protocol (in case of numeric
> conversion/joining).
>
> ## Effect on ABI stability
>
> The hashed container changes are additive so no impact. The switch from
> conrete
> to generic types for the numeric conversions needs to be made before ABI
> stability.
>
> ## Alternatives considered
>
> While they have a convenience benefit as well, this is not the primary
> goal of
> these additions, but a side-effect of helping avoid a performance problem.
> In
> many other cases, the performance issues can be avoided via modified use
> e.g.
> `Sequence.contains` of a `Substring` in a sequence of strings can be
> written as
> `sequence.contains { $0 == substrin

Re: [swift-evolution] Revisiting SE-0110

2017-06-16 Thread rintaro ishizaki via swift-evolution
My guess is that core team is planning to accept *patterns* in closure
parameter clause. e.g.:

  let dict = ["foo": 1, "bar": 2]
  let result = dict.map { ((k, v) : (key: String, value: Int)) in ... }
   ^^ pattern

When the compiler see this expression:

  dict.map { k, v -> R in ... }

1) Always complement () for bare parameters:

  dict.map { (k, v) -> R in ... }

2) If
  a) the context type of the closure has only one parameter with tuple
type; and
  b) closure has the same number of parameters as that tuple type; and
  c) each parameter doesn't have type annotation
treat it as a tuple patten for binding:

  dict.map { ((k, v)) -> R in ... }
  ^^ pattern

3) of that tuple type:

  dict.map { ((k, v): (key: String, value: Int)) -> R in ... }

The important thing here is step 2-c. If the parameters have type
annotations:

  dict.map { (key: String, value: Int) -> R in ... }

We can't use this as a tuple pattern because of the problem we are
discussing right now. In this case, the migrator should rewrite this to:

  dict.map { ((key, value) : (key: String, value: Int)) -> R in ... }

Also, because of that, compiler should reject this confusing tuple pattern.

  dict.map { ((key: String, value: Int)) -> R in ... }
  ^




2017-06-16 14:17 GMT+09:00 David Hart via swift-evolution <
swift-evolution@swift.org>:

>
>
> On 16 Jun 2017, at 01:55, Xiaodi Wu  wrote:
>
> On Thu, Jun 15, 2017 at 17:43 David Hart  wrote:
>
>> On 16 Jun 2017, at 00:41, David Hart  wrote:
>>
>>
>> On 15 Jun 2017, at 19:28, Chris Lattner  wrote:
>>
>>
>> On Jun 15, 2017, at 9:41 AM, Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org> o
>>
>> >
 >   let (a : Int, b : Float) = foo()


 I think it would be better if the compiler raised a warning whenever
 you tried to redefine a builtin type.
>>>
>>>
>>> That’s essentially my preferred solution as well, as it gets to the root
>>> of the confusion.
>>>
>>> Naming a variable the same as a type should be similar to naming a
>>> variable the same as a reserved keyword and require backticks. (A previous
>>> suggestion to enforce capitalization falls down with full Unicode support
>>> and complicates interop where imported C structures might be lowercase and
>>> constants might be all caps.) No need to treat built-in types specially;
>>> it’s equally a problem with types imported from other libraries, which can
>>> be shadowed freely today. For full source compatibility this can be a
>>> warning instead of an error–should be sufficient as long as it’s brought to
>>> the user’s attention. In fact, probably most appropriate as a warning,
>>> since the _compiler_ knows exactly what’s going on, it’s the human that
>>> might be confused.
>>>
>>>
>>> I kind of agree with all you say. But I also feel that tuple element
>>> names in patterns are very rarely used and not worth the added complexity
>>> and confusing. Going back to the old: “Would be add it to Swift if it did
>>> not exist?”, I would say no.
>>>
>>
>> That was the standard for removing features before Swift 3, but with
>> source compatibility the bar is now much higher.
>>
>>
>> Completely agreed.  My belief on this is that it is a legacy Swift 1 type
>> system capability that no one uses.  I have no data to show that though.
>>
>> Is the feature harmful?
>>
>>
>> Yes, absolutely.  The shadowing isn't the thing that bothers me, it is
>> that swift has a meaning for that very syntax in other contexts, and that
>> this is completely different meaning.  People absolutely would get confused
>> by this if they encountered it in real code that they themselves didn't
>> write, and I'm not aware of any good (non theoretical) use for it.
>>
>> My point is, not on its own it isn’t: warning on variables shadowing
>> types is sufficient to resolve the problems shown here.
>>
>>
>> Again, my concern is that this is a confusing and misleading feature
>> which complicates and potentially prevents composing other features in the
>> future.
>>
>>
>>
>> How strange that we’re talking about this issue in a thread about
>> SE-0110.
>>
>>
>> This came up in the discussion about 110 because we were exploring
>> whether it was plausible to expand the function parameter grammar to
>> support destructuring in the position where a name goes.  There are many
>> concerns about whether this is a good idea, but he existence of this in the
>> tuple destructuring pattern grammar is pretty much a showstopper.
>>
>> If anything, the response to that proposal should be a cautionary tale
>> that users can take poorly to removing features, sometimes in unanticipated
>> ways.
>>
>>
>> Agreed, it may be too late to correct this (certainly we can't outright
>> remove it in Swift 4 if someone is using it for something important).
>> However if it turns out that it really isn't used, then warning about it in
>> 4 and removing it shortly after may be possible.
>>
>>
>> And

Re: [swift-evolution] Revisiting SE-0110

2017-06-05 Thread rintaro ishizaki via swift-evolution
2017-06-05 2:16 GMT+09:00 Chris Lattner via swift-evolution <
swift-evolution@swift.org>:

>
> On Jun 1, 2017, at 3:06 PM, John McCall via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>
> On Jun 1, 2017, at 2:39 PM, Pavol Vaskovic  wrote:
>
> On Thu, Jun 1, 2017 at 8:52 PM, John McCall via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>>
>> I understand that there are developers who dislike SE-0110's impact on
>> certain kinds of functional programming, but that is a very broad complaint
>> that is unlikely to reach consensus or acceptance, especially for Swift 4.
>
>
> The impact of SE-0110 as currently implemented in Swift 4 leads to
> following migration choice wherever you have a closure that takes tuple
> argument:
> * concise but obfuscate code ($0.1, ...)
> * readable but verbose code (requiring a ton of boilerplate: intermediate
> argument, expand signature to include return type, desctructure tuple on
> new line using let, add return clause)
>
> Maybe I misunderstood you, but I don't think this is marginal issue
> affecting only some "developers that dislike the impact on certain kinds of
> functional programming".
>
>
> You're misunderstanding me.  I have explicitly said, several times, that I
> agree that the impact on tuple destructuring in closures is a serious
> regression.  There have *also* been objections to losing argument-splat
> behavior, and while that does negatively affect some functional styles, I
> think it would be a mistake to try to address that now.
>
>
> I agree with both points: we need to fix the type checker
> semantics+performance regression, but I also sympathize with the beauty
> regression for closures.  Here are some the examples Gwendal Roué cited
> up-thread (just to make the discussion concrete):
>
> 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() }
>
>
>
>
> One way to split the difference here is to eliminate the splatting
> behavior, but keep the destructuring (irrefutable pattern matching)
> behavior as well.  In these cases, just require an extra explicit paren for
> the parameter list.  This would change the diff's to:
>
> Example 1
> -return columns.index { (column, _) in column.lowercased() ==
> lowercaseName }
> +   return columns.index { ((column, _)) in column.lowercased() ==
> lowercaseName }
>
> Example 2 :
> -.map { (mappedColumn, baseColumn) -> (Int, String) in
> +.map { ((mappedColumn, baseColumn)) -> (Int, String) in
>
> Example 3 :
> -.map { (table, columns) in 
> "\(table)(\(columns.sorted().joined(separator:
> ", ")))" }
> +.map { ((table, columns)) in 
> "\(table)(\(columns.sorted().joined(separator:
> ", ")))" }
>
> Example 4 :
> -dictionary.first { (column, value) in
> column.lowercased() == orderedColumn.lowercased() }
> +dictionary.first { ((column, value)) in
> column.lowercased() == orderedColumn.lowercased() }
>
>
> What do you think?  Seems like it would solve the type checker problem,
> uglify the code a lot less, and make the fixit/migration happily trivial.
>
>
+1.

Migration path would be a little less simple if the parameter clause has
type annotations:

-let fn: Int = { (v: String, k: Int) in
+let fn: Int = { ((v, k): (String, Int)) in

Also, if we accept patterns for closure parameters, we probably don't want
to accept '...' for them.

let fn = { ((_, v): (Int, String)...) -> Int in



> -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] Proposal: Allow #if to guard switch case clauses

2017-05-11 Thread rintaro ishizaki via swift-evolution
Thank you all!


2017-05-11 16:18 GMT+09:00 John McCall via swift-evolution <
swift-evolution@swift.org>:

> On May 11, 2017, at 1:45 AM, Nicholas Maccharoli via swift-evolution <
> swift-evolution@swift.org> wrote:
> I also strongly agree.
>
> I can think of no strong argument against this, was this intentional at
> one point or a compiler bug?
>
>
> The language design of #if is more complex than it is in C: it is part of
> the language grammar, not a separate phase of pre-processing, and must be
> specifically supported in every position it appears.
>
> That said, I agree with Chris and Jordan that supporting #if in any
> simple, sequential position in the grammar is an obvious extension of the
> existing design and can reasonably be fast-tracked.
>
>
So, can I withdraw my proposal PR on swift-evolution repository now?


> Grammatically similar positions where it's hard to dispute the consistency
> argument for #if: get-set clauses, precedencegroup declarations.
>
> A position which would definitely be more useful to prioritize but where
> both the language design and the implementation are trickier: attribute
> lists.
>
>
John.
>
>
> - Nick
>
>
> On Thu, May 11, 2017 at 2:37 PM, Chris Lattner via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> I agree with Jordan.
>>
>> -Chris
>>
>> On May 10, 2017, at 11:47 AM, Jordan Rose via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> I'm in favor, certainly. I'd personally say this wouldn't even need to go
>> through the full evolution process, but I'm not a core team member.
>>
>> Jordan
>>
>>
>> On May 10, 2017, at 01:32, rintaro ishizaki via swift-evolution <
>> swift-evolution@swift.org> wrote:
>>
>> Hi evolution community,
>>
>> This proposal allows you to enclose switch cases with #if directive.
>> Implementation: https://github.com/apple/swift/pull/9457
>> This is one of the oldest SR issue:
>> https://bugs.swift.org/browse/SR-2
>> https://bugs.swift.org/browse/SR-4196
>>
>> Thanks!
>> Rintaro
>>
>>
>> ___
>> 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] Proposal: Allow #if to guard switch case clauses

2017-05-10 Thread rintaro ishizaki via swift-evolution
Here's proposal link:
https://github.com/rintaro/swift-evolution/blob/conditional-switch-case/proposals/-conditional-switch-case.md

Fixed some typos, including my name :)

2017-05-10 17:32 GMT+09:00 rintaro ishizaki :

> Hi evolution community,
>
> This proposal allows you to enclose switch cases with #if directive.
> Implementation: https://github.com/apple/swift/pull/9457
> This is one of the oldest SR issue:
> https://bugs.swift.org/browse/SR-2
> https://bugs.swift.org/browse/SR-4196
>
> Thanks!
> Rintaro
>
>
> Allow #if to guard switch case clauses
>
>- Proposal: SE- 
>- Authors: Rintaro Ishziaki 
>- Review Manager: TBD
>- Status: Awaiting review
>
>
> 
> Introduction
>
> This proposal adds ability to guard switch case clauses with #if
>  directives.
>
> Swift-evolution thread: Not yet
> 
>
> 
> Motivation
>
> When you want to switch cases only for certain compilation condition, say
> switching #if os(Linux) guarded enum cases, right now you have to write
> switch twice:
>
> enum Operation {
>   case output(String)
> #if os(Linux)
>   case syscall(Syscall)
> #endif
> }
> func execute(operation: Operation) {
> #if !os(Linux)
>switch operation {
>case .output(let str):
>print(str)
>}
> #else
>switch operation {
>case .output(let str):
>print(str)
>case .syscall(let call):
>call.execute()
>}
> #endif
> }
>
> This is annoying and error prone.
>
> Proposed
> solution
>
> This proposal allows #if to guard switch case clauses.
>
> func execute(operation: Operation) {
> switch operation {
> case .output(let str):
> print(str)
> #if os(Linux)
> case .syscall(let call):
> call.execute()
> #endif
> }
> }
>
>
> Detailed
> design
>
> This change shouldn't affect existing #if directives *within* case clauses.
> This code should works as expected:
>
> func foo(x: MyEnum) {
> switch x {
> case .some(let str):
> doSomething(str)
> #if PRINT_SOME
> print(str)
> #endif
> case .other:
> doOther()
> }
> }
>
> Only if the next token after #if is case or default, the Parser treat it
> as guarding case clauses.
>
> func foo(x: MyEnum) {
> switch x {
> case .some(let str):
> doSomething(str)
> #if HAS_OTHER
> case .other:
> doOther()
> }
> #endif
> }
>
> func foo(x: MyEnum) {
> switch x {
> case .some(let str):
> doSomething(str)
> #if HAS_OTHER
> default:
> break
> #endif
> }
>
> Error cases:
>
> switch x {
> case .some(let str):
> doSomething(str)
> #if HAS_OTHER
> case .other:
> doOther()
> #else
> doMore() // error: all statements inside a switch must be covered by 
> a 'case' or 'default'#endif
> }
>
> switch x {
> case .some(let str):
> doSomething(str)
> #if HAS_OTHER
> doMore()
> case .other:
> doOther() // error: 'case' label can only appear inside a 'switch' 
> statement#else
> }
>
> You can guard multiple cases as long as it is guarding whole clauses:
>
> switch x {
> case .some(let str):
> doSomething(str)
> #if HAS_OTHERS
> case .other:
> doOther()
> case .more:
> doMore()
> #else
> }
>
>
>
> 
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Proposal: Allow #if to guard switch case clauses

2017-05-10 Thread rintaro ishizaki via swift-evolution
Hi evolution community,

This proposal allows you to enclose switch cases with #if directive.
Implementation: https://github.com/apple/swift/pull/9457
This is one of the oldest SR issue:
https://bugs.swift.org/browse/SR-2
https://bugs.swift.org/browse/SR-4196

Thanks!
Rintaro


Allow #if to guard switch case clauses

   - Proposal: SE- 
   - Authors: Rintaro Ishziaki 
   - Review Manager: TBD
   - Status: Awaiting review


Introduction

This proposal adds ability to guard switch case clauses with #if directives.

Swift-evolution thread: Not yet


Motivation

When you want to switch cases only for certain compilation condition, say
switching #if os(Linux) guarded enum cases, right now you have to write
switch twice:

enum Operation {
  case output(String)
#if os(Linux)
  case syscall(Syscall)
#endif
}
func execute(operation: Operation) {
#if !os(Linux)
   switch operation {
   case .output(let str):
   print(str)
   }
#else
   switch operation {
   case .output(let str):
   print(str)
   case .syscall(let call):
   call.execute()
   }
#endif
}

This is annoying and error prone.
Proposed
solution

This proposal allows #if to guard switch case clauses.

func execute(operation: Operation) {
switch operation {
case .output(let str):
print(str)
#if os(Linux)
case .syscall(let call):
call.execute()
#endif
}
}

Detailed
design

This change shouldn't affect existing #if directives *within* case clauses.
This code should works as expected:

func foo(x: MyEnum) {
switch x {
case .some(let str):
doSomething(str)
#if PRINT_SOME
print(str)
#endif
case .other:
doOther()
}
}

Only if the next token after #if is case or default, the Parser treat it as
guarding case clauses.

func foo(x: MyEnum) {
switch x {
case .some(let str):
doSomething(str)
#if HAS_OTHER
case .other:
doOther()
}
#endif
}

func foo(x: MyEnum) {
switch x {
case .some(let str):
doSomething(str)
#if HAS_OTHER
default:
break
#endif
}

Error cases:

switch x {
case .some(let str):
doSomething(str)
#if HAS_OTHER
case .other:
doOther()
#else
doMore() // error: all statements inside a switch must be
covered by a 'case' or 'default'#endif
}

switch x {
case .some(let str):
doSomething(str)
#if HAS_OTHER
doMore()
case .other:
doOther() // error: 'case' label can only appear inside a
'switch' statement#else
}

You can guard multiple cases as long as it is guarding whole clauses:

switch x {
case .some(let str):
doSomething(str)
#if HAS_OTHERS
case .other:
doOther()
case .more:
doMore()
#else
}



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


Re: [swift-evolution] Inconsistencies in recursive types

2017-03-13 Thread rintaro ishizaki via swift-evolution
final class First {
let item: First
init(item: First) {
self.item = item
}
}

extension First {
convenience init() {
self.init(item: self)
}
}

let a = First()

I'm actually a bit surprised that this compiles.
This should be diagnosed as: "error: 'self' used before self.init call" I
think.


2017-03-13 23:42 GMT+09:00 Dimitri Racordon :

> But then!
>
> The following still shouldn’t compile:
>
> final class First {
> let item: First
> init(item: First) {
> self.item = item
> }
> }
>
>
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Inconsistencies in recursive types

2017-03-13 Thread rintaro ishizaki via swift-evolution
FWIW, there *is* a way to instantiate #4 case.

class First {
let item: First
init(item: First) {
self.item = item
}
}

class Second : First {
init() {
super.init(item: self)
}
}


let a: First = Second()

2017-03-13 22:38 GMT+09:00 Dimitri Racordon via swift-evolution <
swift-evolution@swift.org>:

> Hello swift-evolution,
>
> I noticed there’s some inconsistencies with recursive types and how the
> compiler handles them. Consider the following cases:
>
>
> *1. Swift is right to refuse compiling this, since there’s no way to
> initialise an instance of `First `:*
>
> struct First {
> let item: First
> }
> // Error: Value type 'First' cannot have a stored property that references
> itself
>
> However, the message suggests more a compiler limitation rather than the
> actual impossibility to initialize the declared type.
>
>
> *2. Swift is also right not to compile this, but the error messages are
> even less insightful:*
>
> struct First {
> let item: Second
> }
> // Error: Value type 'First' cannot have a stored property that references
> itself
>
>
> struct Second {
> let item: First
> }
> // Error: Value type 'Second' cannot have a stored property that
> references itself
>
> The problem isn’t that the value types reference *themselves*. Instead,
> the problem is that there’s a cyclic dependency between `First` and
> `Second` that makes it impossible for neither of these structures to be
> instantiated.
>
>
> *3. Swift should let me do that:*
>
> struct First {
> let item: First?
> }
>
> The compiler prevents me to declare the above struct, even if there
> actually is a way to initialise an instance of `First` (e.g. `First(item:
> nil)`). The message is identical to that of case #1 (maybe it actually
> *is* a compiler limitation after all?)
>
>
> *4. Swift shouldn’t compile this:*
>
> class First {
> let item: First
> init(item: First) {
> self.item = item
> }
> }
>
> Like in case #1, there’s no way to instantiate `First`. The fact that it’s
> a reference rather than a value doesn’t change the problem.
>
>
> *5. Similarly to case #4, Swift shouldn’t compile this:*
>
> indirect enum First {
> case item(First)
> }
>
>
> *6. Cases #4 #5 could be written like case #2, and should also raise
> compilation errors.*
>
>
> Does someone know if these issues have already been discussed and/or
> addressed?
>
> Thanks,
> Dimitri Racordon
>
>
> ___
> 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: Compound name `foo(:)` for nullary functions

2017-02-22 Thread rintaro ishizaki via swift-evolution
+1

I prefer foo(:) because it matches with empty dictional literal [:].

Also, foo(_) potentially introduce a confusion.
Remember that this syntax can be appear in a pattern.

```
struct S {
let val: Int
}
func newS() -> S { return S(val: 0) }
func newS(_ val: Int) -> S { return S(val: val) }

func ~= (pat: () -> S, obj: S) -> Bool { return pat().val == obj.val }

let obj = S(val: 0)
switch obj {
case newS(_): // Is this a pattern???
break
default:
break
}
```



2017-02-22 16:05 GMT+09:00 Jacob Bandes-Storch via swift-evolution <
swift-evolution@swift.org>:

> Evolutioniers,
>
> *Compound name syntax* — foo(_:), foo(bar:), foo(bar:baz:) — is used to
> disambiguate references to functions. (You might've used it inside a
> #selector expression.) But there's currently no compound name for a
> function with no arguments.
>
> func foo() {}  // no compound syntax for this one :(
> func foo(_ bar: Int) {}  // foo(_:)
> func foo(bar: Int) {}  // foo(bar:)
> func foo(bar: String, baz: Double) {}  // foo(bar:baz:)
>
> Given these four functions, only the first one has no compound name
> syntax. And the simple reference "let myfn = foo" is ambiguous because it
> could refer to any of the four. A workaround is to specify a contextual
> type, e.g. "let myfn = foo as () -> Void".
>
> I filed SR-3550  for this a while
> ago, and there was some discussion in JIRA about it. I'd like to continue
> exploring solutions here and then write up a formal proposal.
>
> To kick off the discussion, *I'd like to propose foo(:) for nullary
> functions.*
>
> Advantages:
> - the colon marks a clear similarity to the foo(bar:) form when argument
> labels are present.
> - cutely parallels the empty dictionary literal, [:].
>
> Disadvantages:
> - violates intuition about one-colon-per-argument.
> - the parallel between #selector(foo(:)) and @selector(foo) is not quite
> as obvious as between #selector(foo(_:)) and @selector(foo:).
>
>
> For the sake of discussion, another option would be *foo(_)*. This was my
> original choice, and I like that the number of colons matches the number of
> parameters. However, it's a little less obvious as a function reference. It
> would preclude _ from acting as an actual identifier, and might conflict
> with pattern-matching syntax (although it appears functions can't be
> compared with ~= anyway).
>
>
> Looking forward to everyone's bikeshed color ideas,
> Jacob
>
> ___
> 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] Assigning to 'self' in protocol extensions

2017-01-20 Thread rintaro ishizaki via swift-evolution
> In the specific case of initializers, my opinion here is the opposite in
>> fact — I think assigning to ‘self’ should be permitted in all convenience
>> initializers, even initializers defined directly classes, without the
>> protocol extension trick. Also, we should lower this more efficiently than
>> we do today, without creating a self ‘carcass’ that is allocated and
>> immediately freed, to be replaced by the ‘real’ self.
>>
>>
> I totally agree. And I think that is the least impact way on the language
> specification.
>
>
Oops, It seems I have to take back my words.
With my "factory initializer" example:

  let dog = Dog(type: "cat")
  type(of: dog) == Cat.self

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


Re: [swift-evolution] Assigning to 'self' in protocol extensions

2017-01-20 Thread rintaro ishizaki via swift-evolution
2017-01-20 16:11 GMT+09:00 Slava Pestov :

>
> Is your proposal to ban calls to such mutating methods on a type that is
> known to be a reference type at compile time altogether? This will create
> an inconsistency between code that operates on concrete types and code that
> operates on generic parameters (in the latter case the compiler of course
> has no way to statically guarantee that the value is not a reference type).
>
>
The last time this quirk came up in internal discussions, the thought some
> of us had was that it might be worthwhile to prohibit classes from
> conforming to protocols with mutating requirements altogether. If you think
> about it, this makes some amount of sense — it seems like it would be quite
> hard to write code that can operate on both mutable values and mutable
> references generically, since the latter do not have value semantics:
>
> var x = y
> x.mutatingProtocolRequirement()
> // did y change too?
>
> However the discussion sort of fizzled out.
>
> Perhaps we can resurrect it as a proposal, but the bar is pretty high for
> removing features at this point, since there’s no actual type soundness
> issue, just possible confusion.
>
>
Well, I'm not proposing anything for now.
I'm totally OK to leave it as is if the community think so.
If so, I just want to confirm that the language feature truly support this.
At least, I don't want to propose something that breaks source
compatibility.

> Default implementation for initializers
>
> Similar to methods, initializers also have this issue:
>
> In the specific case of initializers, my opinion here is the opposite in
> fact — I think assigning to ‘self’ should be permitted in all convenience
> initializers, even initializers defined directly classes, without the
> protocol extension trick. Also, we should lower this more efficiently than
> we do today, without creating a self ‘carcass’ that is allocated and
> immediately freed, to be replaced by the ‘real’ self.
>
>
I totally agree. And I think that is the least impact way on the language
specification.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Assigning to 'self' in protocol extensions

2017-01-19 Thread rintaro ishizaki via swift-evolution
Hi all,

I just want to raise an issue.
I currently don't have any concrete ideas about it, but I believe we should
discuss this before ABI stabilization.
Default implementation for mutating methods

Swift protocol extension allows assigning to self in default
implementations for mutating methods:

protocol Resettable {
mutating func reset()
init()
}

extension Resettable {
mutating func reset() {
self = Self() // Assigning to 'self'.
}
}

And you can:

class Foo : Resettable {
var value: Int
required init() {
value = 0
}
}

In this example, Foo class conforms to Resettable, by the default
implementation of mutating func reset(). However, this can cause an
unexpected behavior for classes:

var ref1 = Foo()
let ref2 = ref1
assert(ObjectIdentifier(ref1) == ObjectIdentifier(ref2))

ref1.value = 42
assert(ObjectIdentifier(ref1) == ObjectIdentifier(ref2))

ref1.reset()
assert(ObjectIdentifier(ref1) != ObjectIdentifier(ref2))
assert(ref1.value == 0)
assert(ref2.value == 42)

From the perspective of the caller, I think, this behavior is
counterintuitive because we use "reference types" with an expectation: the
referencing address would never be changed *unless* we explicitly replace
the object by re-assigning to the variable in call sites, e.g.,

var ref: Foo = Foo()
ref = Foo()

Default
implementation for initializers

Similar to methods, initializers also have this issue:

protocol HasDefault {
static var _default: Self { get }
init()
}

extension HasDefault {
init() {
self = Self._default // Here it is.
}
}

final class Foo : HasDefault {
let value: Int
init(value: Int) {
self.value = value
}

static var _default = Foo(value: 0)
}

let obj = Foo()
assert(obj.value == 0)

This behavior allows us to implement a kind of "factory initializer".

protocol Factory {
init(factory: () -> Self)
}
extension Factory {
init(factory: () -> Self) {
self = factory()
}
}


class Animal {
var emoji: Character { return "❓" }
}

class Cat : Animal {
override var emoji: Character { return "🐱" }
}

class Dog : Animal {
override var emoji: Character { return "🐶" }
}

extension Animal : Factory {
convenience init(type: String) {
self.init(factory: {
switch type {
case "dog": return Dog()
case "cat": return Cat()
default: return Animal()
}
})
}
}

assert(Animal(type: "dog").emoji == "🐶")

I believe this is *NOT* a right way of implementing factory initializers.
We should introduce a proper "factory initializer" syntax, as discussed in
this ML before.



Any thought?
Do we want to leave them AS IS in Swift4?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Review] SE-0145: Package Manager Version Pinning (Revised)

2016-11-23 Thread rintaro ishizaki via swift-evolution
2016-11-20 14:48 GMT+09:00 Anders Bertelrud via swift-evolution <
swift-evolution@swift.org>:

> Hello Swift community,
>
> The review of "SE-0145: Package Manager Version Pinning" begins again
> after revisions, starting now and running through November 28th. The
> proposal is available here:
>


Overall looks good.

> The exact file format is unspecified/implementation defined, however, in
practice it will be a JSON data file.

Please make it VCS friendly format. If JSON, pretty-print please.

> There will be change in the behaviors of swift build and swift package
update in presence of the pins file, as noted in the proposal

I couldn't find any mention about "swift build" in Proposed Solution or
Detailed Design section.
In case the local workspace has outdated dependencies,
will it automatically fetch pinned versions?
or error-exit indicating I must run "swift package update" first?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Linux specific Package.swift file

2016-11-22 Thread rintaro ishizaki via swift-evolution
Hi Said,

Since `Package.targets` is a mutable public property,
https://github.com/apple/swift-package-manager/blob/master/Sources/PackageDescription/Package.swift#L60-L67
you can freely mutate it later, as documented in
https://github.com/apple/swift-package-manager/blob/master/Documentation/Reference.md#customizing-builds


2016-11-22 4:21 GMT+09:00 Said Sikira via swift-evolution <
swift-evolution@swift.org>:

> Hello everyone,
>
> Currently, we use Package.swift manifest file when defining our packages.
> Within the manifest file you define your targets, dependencies, excluded
> folders etc. This works fairly well while you’re using frameworks that
> exist on all supported platforms (ex. Foundation).
>
> The main problem starts if you want to use code that exists only on macOS
> platform, for example, if you want to use Objective C runtime calls or
> UIKit. Then, you need to use bunch of #if os(Linux) to define what’s
> available on Linux and what’s available on macOS. While this approach can
> be non problematic for simple projects, it can introduce unnecessary
> complexity if you have a large target and dependency graph.
>
> One way people tackle this problem is writing something like this:
>
> #if os(Linux)
> let macOnlyTargets = []
> #else
> let macOnlyTargets = [
> .Target(name: "SomeMacOSTarget")
> ]
> #end
>
> This structure looks even worse if you need to define more complex
> behaviors. For example, look at the RxSwift Package.swift
>  file. In
> my case, I try to write #if os(Linux) as little as possible which leads
> me to writing my packages like:
>
> #if os(Linux)
> // Define full Linux package
> let package = Package(...)
> #else
> // Define full macOS package
> let package = Package(..)
> #end
>
> Proposal
>
> I propose that we support using different file for writing Linux package
> manifests. This file could be named:
>
>- PackageLinux.swift
>- Package.Linux.swift
>- Package.linux.swift
>
> Inside this file you would be able to define your package only for Linux
> in the same way you’re defining one in regular Package.swift. The defined
> behaviors of building a package would be:
>
>1. If building on Linux and PackageLinux.swift is present, use that
>file when building the package.
>2. If building on Linux and PackageLinux.swift is not present, use
>regular Package.swift manifest.
>3. If building on macOS always use Package.swift manifest.
>
> Possible problems
>
> This behavior would only introduce problems when SPM gains support for new
> platforms, but then again, you would need to use new #if os(somethingNew)
> checks.
> Compatibility with current packages
>
> This would be only a additive feature for Swift Package Manager and
> backwards compatibility will be maintained.
>
> ___
> 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] Limiting member expression with right-bound period

2016-11-01 Thread rintaro ishizaki via swift-evolution
2016-11-02 13:14 GMT+09:00 Benjamin Spratling via swift-evolution <
swift-evolution@swift.org>:

>
> CGRect(origin:.zero, size:..
>
> is pretty nice.  Why do you want to get rid of it?
>

No, I'm proposing to reject CGRect(origin:.  zero, size:..)

 '.' whitespace identifier

Reject whitespace in this.

 '.' identifier

is OK.



>
>
> return values
> .flatMap {
>

is OK. but

  return valus
.
flatMap {

should be rejected.



> //code
> }
>
.filter {
> //code
> }
> .sorted { /* code */   }
> .first
>
> is also pretty clean, considering.
>
>
> On Nov 1, 2016, at 11:06 PM, rintaro ishizaki via swift-evolution <
> swift-evolution@swift.org> wrote:
>
> Hi all,
>
> The compiler currently accepts these expressions:
>
> x = expr . member
> x = expr .
>  member
>
> x = expr
> .
>
> member
>
> x = .
>
> implicitMember
>
>
> I propose to reject them because this could cause some unnecessary
> confusion.
> (especially after SE-0071
> <https://github.com/apple/swift-evolution/blob/master/proposals/0071-member-keywords.md>
> )
> For instance:
>
> _ = foo(.
> func bar(x: Int) { ... }
>
>
> The current compiler parses this as:
>
> // call foo(_:_:)
> _ = foo(.func // implicit-member-expression
> // missing ','
> // call bar(x:_:) with argument 'Int' and trailing closure
> bar(x: Int) { ... }
> // missing closing ')'
>
>
> Here's the summary of *current* behavior:
>
> // accept
> expr.member
>
> // accept
> expr .member
>
> // accept
> expr
>   .member
>
> // reject with fix-it to remove white spaces
> expr.  member
>
> // two distinct statements
> expr. // reject as missing member name
>   member
>
> // accept
> expr  .  member
>
> // accept
> expr .
>   member
>
>
> I propose to change the last 2 examples:
>
> // reject with fix-it to remove white spaces
> some  .  member
>
> // two distinct statements
> some . // reject as missing member name
>   member
>
>
> I think, this is consistent behavior with '.' at postfix position.
>
> Specifically:
>
>- If '.' is at *prefix-operator* or *unspaced-binary-operator*
>position, accept.
>- If the next token after '.' is at the same line, propose to fix-it.
>- Otherwise, reject it as missing member name.
>
> This affect following expressions and types in the grammer:
>
> expressions:
>   self-method-expression
>   self-initializer-expression
>   superclass-method-expression
>   superclass-initializer-expression
>   implicit-member-expression
>   initializer-expression
>   explicit-member-expression
>   postfix-self-expression
>   explicit-member-expression
>   postfix-self-expression
> types:
>   type-identifier
>   metatype-type
>
> Of course this is a source breaking change, though.
> Any thought?
>
> ___
> 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] [Pitch] Limiting member expression with right-bound period

2016-11-01 Thread rintaro ishizaki via swift-evolution
Hi all,

The compiler currently accepts these expressions:

x = expr . member
x = expr .
 member

x = expr
.

member

x = .

implicitMember


I propose to reject them because this could cause some unnecessary
confusion.
(especially after SE-0071

)
For instance:

_ = foo(.
func bar(x: Int) { ... }


The current compiler parses this as:

// call foo(_:_:)
_ = foo(.func // implicit-member-expression
// missing ','
// call bar(x:_:) with argument 'Int' and trailing closure
bar(x: Int) { ... }
// missing closing ')'


Here's the summary of *current* behavior:

// accept
expr.member

// accept
expr .member

// accept
expr
  .member

// reject with fix-it to remove white spaces
expr.  member

// two distinct statements
expr. // reject as missing member name
  member

// accept
expr  .  member

// accept
expr .
  member


I propose to change the last 2 examples:

// reject with fix-it to remove white spaces
some  .  member

// two distinct statements
some . // reject as missing member name
  member


I think, this is consistent behavior with '.' at postfix position.

Specifically:

   - If '.' is at *prefix-operator* or *unspaced-binary-operator* position,
   accept.
   - If the next token after '.' is at the same line, propose to fix-it.
   - Otherwise, reject it as missing member name.

This affect following expressions and types in the grammer:

expressions:
  self-method-expression
  self-initializer-expression
  superclass-method-expression
  superclass-initializer-expression
  implicit-member-expression
  initializer-expression
  explicit-member-expression
  postfix-self-expression
  explicit-member-expression
  postfix-self-expression
types:
  type-identifier
  metatype-type

Of course this is a source breaking change, though.
Any thought?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [Review] SE-0144: Allow Single Dollar Sign as a Valid Identifier

2016-10-18 Thread rintaro ishizaki via swift-evolution
   * What is your evaluation of the proposal?

+1
We should do the best to avoid source breaking change in Swift4.
https://github.com/ankurp/Dollar is used in so many projects.
I believe removing this might discourage them from using Swift.

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

Yes

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

No. Also, I personally dislike symbol only identifier.
But IMO, we have to compromise this.

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

Quick reading.


2016-10-15 4:59 GMT+09:00 Chris Lattner via swift-evolution <
swift-evolution@swift.org>:

> Hello Swift community,
>
> The review of "SE-0144: Allow Single Dollar Sign as a Valid Identifier"
> begins now and runs through October 18. The proposal is available here:
>
> https://github.com/apple/swift-evolution/blob/master/proposa
> ls/0144-allow-single-dollar-sign-as-valid-identifier.md
>
> Reviews are an important part of the Swift evolution process. All reviews
> should be sent to the swift-evolution mailing list at
>
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
> or, if you would like to keep your feedback private, directly to the
> review manager.
>
> What goes into a review?
>
> The goal of the review process is to improve the proposal under review
> through constructive criticism and contribute to the direction of Swift.
> When writing your review, here are some questions you might want to answer
> in your review:
>
> * What is your evaluation of the proposal?
> * Is the problem being addressed significant enough to warrant a
> change to Swift?
> * Does this proposal fit well with the feel and direction of Swift?
> * If you have used other languages or libraries with a similar
> feature, how do you feel that this proposal compares to those?
> * How much effort did you put into your review? A glance, a quick
> reading, or an in-depth study?
>
> More information about the Swift evolution process is available at
>
> https://github.com/apple/swift-evolution/blob/master/process.md
>
> Thank you,
>
> -Chris Lattner
> Review Manager
>
>
> ___
> 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] MemoryLayout for a value

2016-08-05 Thread rintaro ishizaki via swift-evolution
2016-08-05 16:20 GMT+09:00 Xiaodi Wu :

> On Fri, Aug 5, 2016 at 2:06 AM, rintaro ishizaki 
> wrote:
>
>> > ```
>> > extension MemoryLayout {
>> >   static func size(ofValue _: T) -> Int { return MemoryLayout.size }
>> >   // etc.
>> > }
>> > ```
>>
>> I don't think we can do this while we have:
>>
>>   public static var size: Int {
>>
>
> Why not?
>

My bad. Sorry, never mind.
I didn't know we can have such overloads (property and func, same basename)
:O



>
> maybe `sizeOf(value _: T) -> Int` ?
>>
>>
>> 2016-08-04 11:28 GMT+09:00 Xiaodi Wu via swift-evolution <
>> swift-evolution@swift.org>:
>>
>>> On Wed, Aug 3, 2016 at 8:47 PM, Erica Sadun via swift-evolution <
>>> swift-evolution@swift.org> wrote:
>>>
 > On Aug 3, 2016, at 2:43 PM, Dave Abrahams via swift-evolution <
 swift-evolution@swift.org> wrote:
 >
 >
 > Having seen the effects in the standard library and in other
 > code, I'm concerned that we may have made a mistake in removing
 > `sizeofValue` et al without providing a replacement.  In the standard
 > library, we ended up adding an underscored API that allows
 >
 >  MemoryLayout._ofInstance(someExpression).size
 >
 > Where someExpression is an autoclosure, and thus not evaluated.  I
 > wanted to bring up the possibility of introducing a replacement as a
 > bufix.
 >
 > I propose that the way to express the above should be:
 >
 >  MemoryLayout.of(type(of: someExpression)).size
 >
 > implementable as:
 >
 >  extension MemoryLayout {
 >@_transparent
 >public
 >static func of(_: T.Type) -> MemoryLayout.Type {
 >  return MemoryLayout.self
 >}
 >  }
 >
 > I think this API would solve the concerns I had about confusability
 that
 > led me to advocate dropping the ability to ask for the size of a
 value.
 > The only way to use it is to pass a type and these two expressions
 have
 > equivalent meaning:
 >
 >MemoryLayout
 >MemoryLayout.of(Int.self)
 >
 > It also has the benefit of isolating the autoclosure magic to
 type(of:).
 >
 > ,[ Aside ]
 > | A slightly cleaner use site is possible with a larger API change:
 > |
 > |   MemoryLayout(type(of: someExpression)).size
 > |
 > | Which would involve changing MemoryLayout from an `enum` to
 > | a `struct` and adding the following:
 > |
 > |   extension MemoryLayout {
 > | public init(_: T.Type) {}
 > |
 > | public var size: Int { return MemoryLayout.size }
 > | public var stride: Int { return MemoryLayout.stride }
 > | public var alignment: Int { return MemoryLayout.alignment }
 > |   }
 > |
 > | However I am concerned that dropping ".of" at the use site is worth
 the
 > | added API complexity.
 > `
 >
 > Thoughts?
 > --
 > -Dave


 I don't think using "of" is a great burden.

>>>
>>> Agreed, but I do think "memory layout of type of my value, size" is a
>>> mouthful compared to "size of value". Moreover, something doesn't sit right
>>> with me that MemoryLayout and MemoryLayout.of(T.self) would be one and
>>> the same thing.
>>>
>>> Could I suggest an alternative? It's conservative in that it mimics the
>>> relationships we had before the proposal was implemented and also maintains
>>> the simplicity of the caseless enum:
>>>
>>> ```
>>> extension MemoryLayout {
>>>   static func size(ofValue _: T) -> Int { return MemoryLayout.size }
>>>   // etc.
>>> }
>>> ```
>>>
>>>
 -- E

 ___
 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] MemoryLayout for a value

2016-08-05 Thread rintaro ishizaki via swift-evolution
> ```
> extension MemoryLayout {
>   static func size(ofValue _: T) -> Int { return MemoryLayout.size }
>   // etc.
> }
> ```

I don't think we can do this while we have:

  public static var size: Int {

maybe `sizeOf(value _: T) -> Int` ?


2016-08-04 11:28 GMT+09:00 Xiaodi Wu via swift-evolution <
swift-evolution@swift.org>:

> On Wed, Aug 3, 2016 at 8:47 PM, Erica Sadun via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> > On Aug 3, 2016, at 2:43 PM, Dave Abrahams via swift-evolution <
>> swift-evolution@swift.org> wrote:
>> >
>> >
>> > Having seen the effects in the standard library and in other
>> > code, I'm concerned that we may have made a mistake in removing
>> > `sizeofValue` et al without providing a replacement.  In the standard
>> > library, we ended up adding an underscored API that allows
>> >
>> >  MemoryLayout._ofInstance(someExpression).size
>> >
>> > Where someExpression is an autoclosure, and thus not evaluated.  I
>> > wanted to bring up the possibility of introducing a replacement as a
>> > bufix.
>> >
>> > I propose that the way to express the above should be:
>> >
>> >  MemoryLayout.of(type(of: someExpression)).size
>> >
>> > implementable as:
>> >
>> >  extension MemoryLayout {
>> >@_transparent
>> >public
>> >static func of(_: T.Type) -> MemoryLayout.Type {
>> >  return MemoryLayout.self
>> >}
>> >  }
>> >
>> > I think this API would solve the concerns I had about confusability that
>> > led me to advocate dropping the ability to ask for the size of a value.
>> > The only way to use it is to pass a type and these two expressions have
>> > equivalent meaning:
>> >
>> >MemoryLayout
>> >MemoryLayout.of(Int.self)
>> >
>> > It also has the benefit of isolating the autoclosure magic to type(of:).
>> >
>> > ,[ Aside ]
>> > | A slightly cleaner use site is possible with a larger API change:
>> > |
>> > |   MemoryLayout(type(of: someExpression)).size
>> > |
>> > | Which would involve changing MemoryLayout from an `enum` to
>> > | a `struct` and adding the following:
>> > |
>> > |   extension MemoryLayout {
>> > | public init(_: T.Type) {}
>> > |
>> > | public var size: Int { return MemoryLayout.size }
>> > | public var stride: Int { return MemoryLayout.stride }
>> > | public var alignment: Int { return MemoryLayout.alignment }
>> > |   }
>> > |
>> > | However I am concerned that dropping ".of" at the use site is worth
>> the
>> > | added API complexity.
>> > `
>> >
>> > Thoughts?
>> > --
>> > -Dave
>>
>>
>> I don't think using "of" is a great burden.
>>
>
> Agreed, but I do think "memory layout of type of my value, size" is a
> mouthful compared to "size of value". Moreover, something doesn't sit right
> with me that MemoryLayout and MemoryLayout.of(T.self) would be one and
> the same thing.
>
> Could I suggest an alternative? It's conservative in that it mimics the
> relationships we had before the proposal was implemented and also maintains
> the simplicity of the caseless enum:
>
> ```
> extension MemoryLayout {
>   static func size(ofValue _: T) -> Int { return MemoryLayout.size }
>   // etc.
> }
> ```
>
>
>> -- E
>>
>> ___
>> 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] Move @noescape and @autoclosure to type attributes

2016-03-27 Thread rintaro ishizaki via swift-evolution
After this proposal [SE-0049] is accepted:

Is the following code valid?

func foo(arg: @autoclosure () -> Bool) { }
let value: @autoclosure () -> Bool = false
foo(value)

If so, I feel `@autoclosure T` is more natural than `@autoclosure () -> T`

let value: @autoclosure Bool = false
func foo(arg: @autoclosure Bool) {
   if arg() { ... }
}
foo(x)



2016-03-10 14:38 GMT+09:00 Chris Lattner via swift-evolution <
swift-evolution@swift.org>:

>
> *Introduction*
> This proposal suggests moving the existing @noescape and @autoclosure
> attributes from being declaration attributes on a parameter to being type
> attributes.  This improves consistency and reduces redundancy within the
> language, e.g. aligning with the previous Swift 3 decision to move “inout”,
> and making declaration and type syntax more consistent.
>
> Swift-evolution thread: 
>
>
> *Motivation*
> Chris Eidhof noticed an emergent result of removing our currying syntax:
> it broke some useful code using @noescape, because we only allowed it on
> parameter declarations, not on general things-of-function-type.  This meant
> that manually curried code like this:
>
> func curriedFlatMap(x: [A]) -> (@noescape A -> [B]) -> [B] {
>return { f in
>x.flatMap(f)
>}
> }
>
> Was rejected.  Fixing this was straight-forward (
> https://github.com/apple/swift/commit/c3c6beac72bc0368030f06d52c46b6444fc48dbd),
> but required @noescape being allowed on arbitrary function types.  Now that
> we have that, these two declarations are equivalent:
>
> func f(@noescape fn : () -> ()) {}  // declaration attribute
> func f(fn : @noescape () -> ()) {}  // type attribute.
>
> Further evaluation of the situation found that @autoclosure (while less
> pressing) has the exact same problem.  That said, it is currently in a
> worse place than @noescape because you cannot actually spell the type of a
> function that involves it.   Consider an autoclosure-taking function like
> this:
>
> func f2(@autoclosure a : () -> ()) {}
>
> You can use it as you’d expect, e.g.:
>
> f2(print("hello”))
>
> Of course, f2 is a first class value, so you can assign it:
>
> let x = f2
> x(print("hello"))
>
> This works, because x has type "(@autoclosure () -> ()) -> ()”.  You can
> see this if you force a type error:
>
> let y : Int = x // error: cannot convert value of type '(@autoclosure ()
> -> ()) -> ()' to specified type 'Int'
>
> However, you can’t write this out explicitly:
>
> let x2 : (@autoclosure () -> ()) -> () = f2
> // error: attribute can only be applied to declarations, not types
>
> This is unfortunate because it is an arbitrary inconsistency in the
> language, and seems silly that you can use type inference but not manual
> specification for the declaration of x2.
>
>
> *Proposed solution*
> The solution solution is straight-forward: disallow @noescape and
> @autoclosure on declarations, and instead require them on the types.  This
> means that only the type-attribute syntax is supported:
>
> func f(fn : @noescape () -> ()) {}  // type attribute.
> func f2(a : @autoclosure () -> ()) {}  // type attribute.
>
> This aligns with the syntax used for types, since the type of “f” is
> “(_: @noescape () -> ()) -> ()”, and the type of “f2” is “(_ : @autoclosure
> () -> ()) -> ()”.  This fixes the problem with x2, and eliminates the
> redundancy between the @noescape forms.
>
>
> *Impact on existing code*
> This breaks existing code that uses these in the old position, so it would
> be great to roll this out with the other disruptive changes happening in
> Swift 3.  The Swift 3 migrator should move these over, and has the
> information it needs to do a perfect migration in this case.
>
> For the compiler behavior, given that Swift 2.2 code will be source
> incompatible with Swift 3 code in general, it seems best to make these a
> hard error in the final Swift 3 release.  It would make sense to have a
> deprecation warning period for swift.org projects like corelibs and
> swiftpm, and other open source users tracking the public releases though.
>
> -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] [Proposal] Factory Initializers

2016-03-24 Thread rintaro ishizaki via swift-evolution
FWIW, even in Swift2, factory initializer is possible.

I've post a gist here:
https://gist.github.com/rintaro/9eadc2720ac8be6a7898
It's pretty hackish though :)


2016-03-22 15:16 GMT+09:00 Riley Testut via swift-evolution <
swift-evolution@swift.org>:

> Hey all!
>
> Very sorry, restored my MacBook at the beginning of the calendar year, and
> forgot to re-subscribe to Swift-Evolution 😄. Once I realized this, I
> decided to hold off on pushing this forward till after Swift 2.2, and now
> that it's been released, I'd love to make moves on this!
>
> So, is there still an interest in the proposal? If so, I'll write up a new
> proposal with everyone's feedback, and then post it here for more
> discussion. I think this would very valuable (and would certainly help a
> bunch in my current app), but want to see where everyone stands!
>
> Riley Testut
>
> On Feb 8, 2016, at 11:26 AM, Charles Srstka 
> wrote:
>
> >> On Dec 17, 2015, at 3:41 PM, Riley Testut via swift-evolution <
> swift-evolution@swift.org> wrote:
> >>
> >> Recently, I proposed the idea of adding the ability to implement the
> "class cluster" pattern from Cocoa (Touch) in Swift. However, as we
> discussed it and came up with different approaches, it evolved into a
> functionality that I believe is far more beneficial to Swift, and
> subsequently should be the focus of its own proposal. So here is the
> improved (pre-)proposal:
> >>
> >> # Factory Initializers
> >>
> >> The "factory" pattern is common in many languages, including
> Objective-C. Essentially, instead of initializing a type directly, a method
> is called that returns an instance of the appropriate type determined by
> the input parameters. Functionally this works well, but ultimately it
> forces the client of the API to remember to call the factory method
> instead, rather than the type's initializer. This might seem like a minor
> gripe, but given that we want Swift to be as approachable as possible to
> new developers, I think we can do better in this regard.
> >>
> >> Rather than have a separate factory method, I propose we build the
> factory pattern right into Swift, by way of specialized “factory
> initializers”. The exact syntax was proposed by Philippe Hausler from the
> previous thread, and I think it is an excellent solution:
> >>
> >> class AbstractBase {
> >>   public factory init(type: InformationToSwitchOn) {
> >>   return ConcreteImplementation(type)
> >>   }
> >> }
> >>
> >> class ConcreteImplementation : AbstractBase {
> >>
> >> }
> >>
> >> Why exactly would this be useful in practice? In my own development,
> I’ve come across a few places where this would especially be relevant:
> >>
> >> ## Class Cluster/Abstract Classes
> >> This was the reasoning behind the original proposal, and I still think
> it would be a very valid use case. The public superclass would declare all
> the public methods, and could delegate off the specific implementations to
> the private subclasses. Alternatively, this method could be used as an easy
> way to handle backwards-compatibility: rather than litter the code with
> branches depending on the OS version, simply return the OS-appropriate
> subclass from the factory initializer. Very useful.
> >>
> >> ## Protocol Initializers
> >> Proposed by Brent Royal-Gordon, we could use factory initializers with
> protocol extensions to return the appropriate instance conforming to a
> protocol for the given needs. Similar to the class cluster/abstract class
> method, but can work with structs too. This would be closer to the factory
> method pattern, since you don’t need to know exactly what type is returned,
> just the protocol it conforms to.
> >>
> >> ## Initializing Storyboard-backed View Controller
> >> This is more specific to Apple Frameworks, but having factory
> initializers could definitely help here. Currently, view controllers
> associated with a storyboard must be initialized from the client through a
> factory method on the storyboard instance (storyboard.
> instantiateViewControllerWithIdentifier()). This works when the entire flow
> of the app is storyboard based, but when a single storyboard is used to
> configure a one-off view controller, having to initialize through the
> storyboard is essentially use of private implementation details; it
> shouldn’t matter whether the VC was designed in code or storyboards,
> ultimately a single initializer should “do the right thing” (just as it
> does when using XIBs directly). A factory initializer for a View Controller
> subclass could handle the loading of the storyboard and returning the
> appropriate view controller.
> >>
> >> Here are some comments from the previous thread that I believe are
> still relevant:
> >>
> >>
> >>> On Dec 9, 2015, at 1:06 PM, Philippe Hausler 
> wrote:
> >>>
> >>> I can definitely attest that in implementing Foundation we could have
> much more idiomatic swift and much more similar behavior to the way
> Foundation on Darwin actually works if we had factory

Re: [swift-evolution] [Draft] Abolish IUO type

2016-03-19 Thread rintaro ishizaki via swift-evolution
What will happen to map()/flatMap() on IUO attributed optional values?

let foo: Int! = 42
let bar = (foo as ImplicitlyUnwrappedOptional).map { $0.UInt($0) }


Replacement would be something like this?

let bar: UInt! = (foo as Int?).map { UInt($0) }


I have never seen code like this in real world,
but it should be covered in "Impact on existing code" section.


2016-03-18 13:12 GMT+09:00 Chris Lattner via swift-evolution <
swift-evolution@swift.org>:

>
> > On Mar 17, 2016, at 9:08 PM, Chris Lattner via swift-evolution <
> swift-evolution@swift.org> wrote:
> >
> > On Mar 17, 2016, at 5:50 PM, Brent Royal-Gordon 
> wrote:
> >
> >>> It seems like this unnecessarily complicates the surface model of
> Swift.  To me, it seems like there is no advantage to having two ways to
> spell this.
> >>
> >>   @autounwrapped let foo = functionReturningOptional()
> >>
> >> I *believe* that, without the `@autounwrapped` attribute, there's no
> way to go from T? to T! without actually restating T somewhere.
> >
> > Right, that's part of the feature :-)
>
> Sorry, less snarky answer:
>
> You are right that today it is a regression vs:
>
> let foo : ImplicitlyUnwrappedOptional = ...
>
> However, I have never seen someone actually do that, and if they did, I
> would observe that the T is a lot more illuminating than the ! part of the
> type.  Is there a concrete use case you are concerned about?
>
> -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] [Draft] Abolish IUO type

2016-03-19 Thread rintaro ishizaki via swift-evolution
Oops, typo in the example code:

let foo: Int! = 42
let bar = (foo as ImplicitlyUnwrappedOptional).map { UInt($0) }


2016-03-18 14:05 GMT+09:00 rintaro ishizaki :

> What will happen to map()/flatMap() on IUO attributed optional values?
>
> let foo: Int! = 42
> let bar = (foo as ImplicitlyUnwrappedOptional).map { $0.UInt($0) }
>
>
> Replacement would be something like this?
>
> let bar: UInt! = (foo as Int?).map { UInt($0) }
>
>
> I have never seen code like this in real world,
> but it should be covered in "Impact on existing code" section.
>
>
> 2016-03-18 13:12 GMT+09:00 Chris Lattner via swift-evolution <
> swift-evolution@swift.org>:
>
>>
>> > On Mar 17, 2016, at 9:08 PM, Chris Lattner via swift-evolution <
>> swift-evolution@swift.org> wrote:
>> >
>> > On Mar 17, 2016, at 5:50 PM, Brent Royal-Gordon 
>> wrote:
>> >
>> >>> It seems like this unnecessarily complicates the surface model of
>> Swift.  To me, it seems like there is no advantage to having two ways to
>> spell this.
>> >>
>> >>   @autounwrapped let foo = functionReturningOptional()
>> >>
>> >> I *believe* that, without the `@autounwrapped` attribute, there's no
>> way to go from T? to T! without actually restating T somewhere.
>> >
>> > Right, that's part of the feature :-)
>>
>> Sorry, less snarky answer:
>>
>> You are right that today it is a regression vs:
>>
>> let foo : ImplicitlyUnwrappedOptional = ...
>>
>> However, I have never seen someone actually do that, and if they did, I
>> would observe that the T is a lot more illuminating than the ! part of the
>> type.  Is there a concrete use case you are concerned about?
>>
>> -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