Re: [swift-evolution] Specified Protocol Conformances in Subclasses

2017-03-10 Thread Anton Zhilin via swift-evolution
Looks like a compiler bug, since it works with classes:

class Base {}class Derived : Base {}
class A {
var x: Base? { return Base() }
}
class B : A {
override var x: Derived? { return Derived() }
}

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


Re: [swift-evolution] Should explicit `self.` be required when providing method as closure?

2017-03-04 Thread Anton Zhilin via swift-evolution
I disagree with dropping function references in general, but I do agree
with limiting partially applied method references.

In @escaping arguments, adding self. won’t add enough evidence that it
actually creates a closure with capture.
Even in non-escaping context, I find plain method references odd:

func square(_ x: Int) -> Int { … }

(1...10).map(square)  // totally ok with that
class SomeClass {
func foo(_ x: Int) -> Int { … }

func bar() {
(1...10).map(foo)   // what??
(1...10).map(self.foo)  // ok
someControl.addHandler(self.foo)  // should be error if @escaping?
}
}

2017-03-04 10:09 GMT+03:00 David Hart via swift-evolution <
swift-evolution@swift.org>:

I encountered this precise memory leak in my code a few days ago, so I
> sympathize. A second solution would be to drop function references. I think
> a core team member suggested it on another thread.

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


Re: [swift-evolution] [Discussion] What is the future of tuples in Swift?

2017-03-02 Thread Anton Zhilin via swift-evolution
2017-03-03 2:13 GMT+03:00 Slava Pestov :

Does newtype add any new capability that’s not already covered by defining
> a struct?
>
newtype would forward all members and conformances of the underlying type:

newtype RecordId = Int
let x: RecordId = 5let y = x + 10
extension RecordId {
func load() -> String { … }
}
let a = x.load()let b = 42.load()  // error

newtypes aim to carry purely semantic information, in this case, that those
integers can be used to fetch records from a database. We get additional
members only when we are sure that semantic of current instance is
appropriate.

As a side effect, it essentially allows to declare one-liner structs with
pattern matching. But I agree with Jaden, just adding pattern matching to
structs feels more practical. And this feature is more or less orthogonal
to the core functionality of newtype.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Discussion] What is the future of tuples in Swift?

2017-03-02 Thread Anton Zhilin via swift-evolution
I think that tuples should remain what they are now. Static-length vectors
should be types on their own and interact with tuples, with structs and
with Array<…> in the same way.

newtype should be what enables extension of tuples:

newtype Money = (Int, Int)
extension Money: CustomStringConvertible {
var description: String {
return String(format: "$%d.%02d", arguments: [getSelfFirst,
getSelfSecond])
}
}
let x = (0, 42)let y = x as Money  // errorprint(x.description)  // error
let z = Money(0, 42)print(z.description)  //=> $0.42

Here, getSelfFirst and getSelfSecond are placeholders for some syntax to
access the underlying type.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Discussion] Simplifying case syntax

2017-03-02 Thread Anton Zhilin via swift-evolution
Hi Erica, thanks for restarting the discussion—I hope that it will be
considered on topic for stage 2.

I agree that the part with preventing let .case(existingVar, newVar) should
be moved out of the proposal, because these issues are orthogonal. So the
options with ~= and := will differ only in that the former overloads an
existing custom operator.

I prefer the version with keywords instead of operators, because
overloading any custom operator can be confusing.

I think that pattern should be on the right, because that’s the order of
computation: first the expression, then pattern matching. That’s also how
switch looks: first expression, then patterns.

// That's what current if-case looks like. Counterintuitive!do {
case .success(let value): …
case .failure(let value): …
} switch computeResult(foo(frobnicate), bar)

Examples with matches and is, for extra brevity:

if computeResult(foo(frobnicate), bar) matches .success(let value) { … }
if computeResult(foo(frobnicate), bar) is .success(let value) { … }

I also considered using ->. It would never be ambiguous in this context,
but keywords still look better IMO:

if computeResult(foo(frobnicate), bar) -> .success(let value) { … }

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


Re: [swift-evolution] 'T != Type' in where clause

2017-02-28 Thread Anton Zhilin via swift-evolution
But it already works without where T != Self. Moreover, I guess, this
solution is currently considered “good enough” not to introduce additional
complexity to type system.
Also, on and and or—the former already exists in the form of &, and the
latter is listed in commonly proposed rejected features.

2017-02-28 7:23 GMT+03:00 Robert Bennett via swift-evolution <
swift-evolution@swift.org>:

protocol P1 {}

protocol P2 {
// Now, there's no ambiguity
static func +(lhs: Self, rhs: T) -> Self
static func +(lhs: T, rhs: Self) -> Self
static func +(lhs: Self, rhs: Self) -> Self
}

struct S: P1, P2 {
static func +(lhs: T, rhs: S) -> S {
return rhs
}
static func +(lhs: S, rhs: T) -> S {
return lhs
}
static func +(lhs: S, rhs: S) -> S {
return lhs
}
}

Some thought would have to be given to how to handle subtype relationships
— probably you would use the polymorphic type of the object at the call
site.

​
___
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-24 Thread Anton Zhilin via swift-evolution
+1 to foo(:) version.
I can easily see placeholder arguments as a sugary syntax for closures:

func bar(_ x: Int, _ y: Double)
let f = bar(_, 42)   // the same as:
let f = { (x: Int) in bar(x, 42) }

Now, let’s view a single-parameter version:

func foo(_ x: Int)
let f = foo(_)   // the same as:
let f = { (x: Int) in foo(x) }

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


Re: [swift-evolution] [Discussion] Analysis of the design of typed throws

2017-02-24 Thread Anton Zhilin via swift-evolution
2017-02-23 21:01 GMT+03:00 Matthew Johnson :
>
> I don’t understand what you mean here.
>

I was a bit confused. Thanks to your clarification, I discovered that
`rethrows` functions currently can use `throw` expression, but only in
`catch` scope, which handles error handling for one of function parameters.
In my view, this language feature should be removed without replacement if
we remove `rethrows`. Instead, we should always be able to throw error type
stated in `throws(...)`.

I don’t understand what you mean here.  In this alternative design *all*
> functions / closures / methods have an error type.  If one is not stated
> explicitly it defaults to `Never`.  If `throws` is specified without a type
> it defaults to `Error`.  There is no burden at all placed on callers.
>

I meant that in that specific case I would prefer returning an optional. If
error value is not meaningful--and that is the case with `f` function
parameter and corresponding `F` error type--then we are dealing with simple
domain errors, which are expressed with returning optionals instead of
throwing. I'll include this example anyway.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Discussion] Analysis of the design of typed throws

2017-02-24 Thread Anton Zhilin via swift-evolution
When I started changing the proposal, I noticed that examples with throws(E)
look uglier than with rethrows, because of required constraint of E: Error.
So I’d like to also discuss removal of Error constraint and its
consequences. Some people talked about Objective-C interop. What are those
issues?
More than that, it would then be logical to remove Error altogether and
move localizedDescription to LocalizedError.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Discussion] Analysis of the design of typed throws

2017-02-23 Thread Anton Zhilin via swift-evolution
2017-02-23 20:09 GMT+03:00 Matthew Johnson :

>
> On Feb 23, 2017, at 10:58 AM, Anton Zhilin  wrote:
>
> See some inline response below.
> Also, have you seen the issue I posted in Proposal thread? There is a way
> to create an instance of "any" type.
>
>
> Yes, I saw that.  There is no problem with that at all.  As I point out in
> the analysis below, rethrowing functions are allowed to throw any error
> they want.  They are only limited by *where* they may throw.
>

OK, if a function throws on itself (which is an unusual situation), it will
state its semantics in documentation, and it's the right place to do that.

> Yes, upcasting is only one way (besides others) to convert to a common
> error type. That's what I had in mind, but I'll state it more explicitly.
>
> The important point is that if you include `rethrows` it should not place
> any restrictions on the type that it throws when its arguments throw.  All
> it does is prevent the function from throwing unless there is a dynamic
> guarantee that one of the arguments did in fact throw (which of course
> means if none of them can throw then the rethrowing function cannot throw
> either).
>

Yes, I understood that.

> Yes, any empty type should be allowed instead of just `Never`. That's a
> general solution to the ploblem with `rethrows` and multiple throwing
> parameters.
>
>
> It looks like you clipped out the section "Why this solution is better”
> which showed how `rethrows` is not capable of correctly typing a function
> as non-throwing if it dynamically handles all of the errors thrown by its
> arguments.  What do you think of that?  In my opinion, it makes a strong
> case for eliminating rethrows and introducing the uninhabited type solution
> from the beginning.
>

I'm positive about baking removal of `rethrows` into the proposal.
The specific example seems superficial to me. Usually we want to require
the bare minimum from the caller. But here we require a proper error type,
which is never used. Although, it may just be a convenience overload, and
the other overload accepts `() -> Bool` or `() -> Void?`.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Discussion] Analysis of the design of typed throws

2017-02-23 Thread Anton Zhilin via swift-evolution
See some inline response below.
Also, have you seen the issue I posted in Proposal thread? There is a way
to create an instance of "any" type.

2017-02-23 3:37 GMT+03:00 Matthew Johnson via swift-evolution <
swift-evolution@swift.org>:

> # Analysis of the design of typed throws
>
> ## Problem
>
> There is a problem with how the proposal specifies `rethrows` for
> functions that take more than one throwing function.  The proposal says
> that the rethrown type must be a common supertype of the type thrown by all
> of the functions it accepts.  This makes some intuitive sense because this
> is a necessary bound if the rethrowing function lets errors propegate
> automatically - the rethrown type must be a supertype of all of the
> automatically propegated errors.
>
> This is not how `rethrows` actually works though.  `rethrows` currently
> allows throwing any error type you want, but only in a catch block that
> covers a call to an argument that actually does throw and *does not* cover
> a call to a throwing function that is not an argument.  The generalization
> of this to typed throws is that you can rethrow any type you want to, but
> only in a catch block that meets this rule.
>
>
> ## Example typed rethrow that should be valid and isn't with this proposal
>
> This is a good thing, because for many error types `E` and `F` the only
> common supertype is `Error`.  In a non-generic function it would be
> possible to create a marker protocol and conform both types and specify
> that as a common supertype.  But in generic code this is not possible.  The
> only common supertype we know about is `Error`.  The ability to catch the
> generic errors and wrap them in a sum type is crucial.
>
> I'm going to try to use a somewhat realistic example of a generic function
> that takes two throwing functions that needs to be valid (and is valid
> under a direct generalization of the current rules applied by `rethrows`).
>
> enum TransformAndAccumulateError {
>case transformError(E)
>case accumulateError(F)
> }
>
> func transformAndAccumulate(
>_ values: [T],
>_ seed: V,
>_ transform: T -> throws(E) U,
>_ accumulate: throws (V, U) -> V
> ) rethrows(TransformAndAccumulateError) -> V {
>var accumulator = seed
>try {
>   for value in values {
>  accumulator = try accumulate(accumulator, transform(value))
>   }
>} catch let e as E {
>   throw .transformError(e)
>} catch let f as F {
>   throw .accumulateError(f)
>}
>return accumulator
> }
>
> It doesn't matter to the caller that your error type is not a supertype of
> `E` and `F`.  All that matters is that the caller knows that you don't
> throw an error if the arguments don't throw (not only if the arguments
> *could* throw, but that one of the arguments actually *did* throw).  This
> is what rethrows specifies.  The type that is thrown is unimportant and
> allowed to be anything the rethrowing function (`transformAndAccumulate` in
> this case) wishes.
>

Yes, upcasting is only one way (besides others) to convert to a common
error type. That's what I had in mind, but I'll state it more explicitly.


> ## Eliminating rethrows
>
> We have discussed eliminating `rethrows` in favor of saying that
> non-throwing functions have an implicit error type of `Never`.  As you can
> see by the rules above, if the arguments provided have an error type of
> `Never` the catch blocks are unreachable so we know that the function does
> not throw.  Unfortunately a definition of nonthrowing functions as
> functions with an error type of `Never` turns out to be too narrow.
>
> If you look at the previous example you will see that the only way to
> propegate error type information in a generic function that rethrows errors
> from two arguments with unconstrained error types is to catch the errors
> and wrap them with an enum.  Now imagine both arguments happen to be
> non-throwing (i.e. they throw `Never`).  When we wrap the two possible
> thrown values `Never` we get a type of `TransformAndAccumulateError Never>`.  This type is uninhabitable, but is quite obviously not `Never`.
>
> In this proposal we need to specify what qualifies as a non-throwing
> function.  I think we should specifty this in the way that allows us to
> eliminate `rethrows` from the language.  In order to eliminate `rethrows`
> we need to say that any function throwing an error type that is
> uninhabitable is non-throwing.  I suggest making this change in the
> proposal.
>
> If we specify that any function that throws an uninhabitable type is a
> non-throwing function then we don't need rethrows.  Functions declared
> without `throws` still get the implicit error type of `Never` but other
> uninhabitable error types are also considered non-throwing.  This provides
> the same guarantee as `rethrows` does today: if a function simply
> propegates the errors of its arguments (implicitly or by manual wrapping)
> and all 

Re: [swift-evolution] [Proposal] Typed throws

2017-02-22 Thread Anton Zhilin via swift-evolution
As a follow-up, here is code that you can test now. It demonstrates the
same, but with normal function result.

func createArbitrary(usingGenerator f: () -> (T)) -> T {
let any: Any = 42 as Any
if Int.self is T.Type {
let t = any as! T
return t
}
return f()
}
print(createArbitrary(usingGenerator: { return 5 }))  //=> 42

And yes, nobody should do these tricks in production code :P

2017-02-22 21:15 GMT+03:00 Anton Zhilin :

I understand how parametric polymorphism works *in Haskell*. But we talk
> about Swift, and there *is* a way to get an instance of E. I’ll explain
> it another way:
>
> func bypassRethrows(_ f: () throws(E) -> ()) throws(E) {
> let error: Error = MyError()  // create an instance of `MyError`
> if MyError.self is E.Type {   // in case `E` happens to be `MyError`
> let e: E = error as! E// then we've actually created an instance 
> of `E`, and we can downcast safely
> throw e   // voila, acquired an instance of `E`
> }
> }
> let f: () throws MyError -> () = { }
> try bypassRethrows(f) // actually throws `MyError`, without ever 
> calling `f`
>
> What line here seems impossible?
>
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Typed throws

2017-02-22 Thread Anton Zhilin via swift-evolution
I understand how parametric polymorphism works *in Haskell*. But we talk
about Swift, and there *is* a way to get an instance of E. I’ll explain it
another way:

func bypassRethrows(_ f: () throws(E) -> ()) throws(E) {
let error: Error = MyError()  // create an instance of `MyError`
if MyError.self is E.Type {   // in case `E` happens to be `MyError`
let e: E = error as! E// then we've actually created an
instance of `E`, and we can downcast safely
throw e   // voila, acquired an instance of `E`
}
}
let f: () throws MyError -> () = { }
try bypassRethrows(f) // actually throws `MyError`,
without ever calling `f`

What line here seems impossible?

2017-02-22 18:39 GMT+03:00 Matthew Johnson :

No because there are many types that conform to `Error` but are not `E` and
> the signature says you only throw `E`.  You have no way to get an instance
> of `E` except by catching one thrown by `f` because `Error` does not have
> any initializers and you don’t have any visibility to anything that
> provides an `E` in any way except when `f` throws.
>
> I am hoping to have time to write up my analysis of generic rethrowing
> functions later today.  There are some very interesting tradeoffs we need
> to make.
>
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Typed throws

2017-02-22 Thread Anton Zhilin via swift-evolution
How about this:

func bypassRethrows(_ f: () throws(E) -> ()) throws(E) {
if let e = (MyError() as Error) as? E {
throw e
}
}

I obviously can’t “test” this right now, but should work?

2017-02-22 3:42 GMT+03:00 Colin Barrett <co...@springsandstruts.com>:

On Sun, Feb 19, 2017 at 2:34 PM Anton Zhilin via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> Now that I think about it, generic throws does not exactly cover rethrows
>> .
>> Firstly, rethrows has semantic information that function itself does not
>> throw—it would be lost.
>>
> That's not true. Parametric polymorphism guarantees that rethrows and
> polymorphic throw are the same.
>
> For example, you can prove that as a consequence of parametricity that
> there is only one (pure) function in the of the set of all functions with
> the type ``forall A. A -> A'' and furthermore that it is the identity
> function.
>
> The intuition behind this is that you (meaning the fiction; imagine being
> a function!) cannot construct your own value of "A" since you don't have
> any information about what "A" is. The only place to get an "A" is from
> your argument.
>
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Typed throws

2017-02-20 Thread Anton Zhilin via swift-evolution
2017-02-21 1:21 GMT+03:00 Matthew Johnson :
>
> Thanks for the links.  I scanned through them somewhat quickly and didn’t
> see anything that specifically said `Never` should conform to all
> protocols.  Did you see that specifically?  I only saw mentions of it being
> a bottom type and therefore a subtype of all types, which I think is a bit
> different.
>
> I think a big part of the confusion here revolves around the distinction
> between a type `T` being a subtype of another type `U` and `Type` being
> a subtype of `Type` (using the syntax in your metatype refactoring
> proposal).  I’m not an expert in this area, but I suspect that `Never` can
> be a subtype of all existential types but without requiring it to actually
> *conform* to all protocols.  Any non-instance protocol requirements are not
> available on existentials (afaik).
>

I didn't fully understand about metatypes, but otherwise yes indeed.

Yes, I understood the example and it’s a good one.  What I’m wondering is
> what benefit you actually get from this.  There are two places where this
> default initializer could be used:
>
> 1. In `seq` itself.  But it seems highly dubious to throw an error you
> know nothing about.  Why does `seq` need the ability to construct an error
> of the same type as a function given to it without knowing anything more
> about that error type.  Is there a use case for this?
> 2. In callers of `seq`.  Why would the caller care if the error type that
> `seq` can throw has a default initializer?  Is there a use case for this?
>
> In other words, why do you want to specify that the type of error that
> might be thrown must have a default initializer?  I can’t think of any
> possible circumstance where this would be valuable.
>
> The same question can be asked of any other static requirements.  What are
> the use cases?  These seem highly theoretical to me.  Maybe I’m missing
> something, but if so I would like to see an example of how it is *used*,
> not just how you would need to write an extra overload without `rethrows`.
>

Seems highly theoretical to me as well.

There is a potentially more practical benefit of keeping rethrows.  If a
> function is declared with `rethrows` we know that the function itself does
> not throw.  It only throws if one of its arguments throw when it invokes
> them.  This is a subtle but important difference.  For example, users
> calling a rethrowing function know that *they* have control over whether or
> not the call *actually* throws.  The caller might pass a couple of
> functions that *can* throw but in this particular case are known not to
> throw.  That could influence how the caller handles errors in the
> surrounding scope.
>

Agreed. Now I lean towards leaving the proposal as is.

2017-02-21 1:21 GMT+03:00 Matthew Johnson :

>
> On Feb 20, 2017, at 11:14 AM, Anton Zhilin  wrote:
>
> 2017-02-20 18:23 GMT+03:00 Matthew Johnson :
>
>
>
>> On Feb 20, 2017, at 3:58 AM, Anton Zhilin  wrote:
>>
>> But that raises another concern. In a previous discussion, it was taken
>> for granted that Never should conform to all protocols
>>
>> Do you have a pointer to this discussion?  I must have missed it.
>>
>
>
> Here
> 
> is the discussion where the idea of “empty” type originated.
> Some messages on the topic ended up being there
> .
>
> This  is the
> earliest mention of usage of this empty type for rethrows I could find.
> Some related messages are here
> 
> as well.
>
> We called this type NoReturn and meant it to be the *bottom type*, i.e.
> subtype of all types, meaning that if you have an instance of NoReturn—which
> can only happen in unreachable sections of code—then you can convert it to
> any type. It should have worked like this:
>
> func fatalError() -> Never
>
> func divide(a: Int, b: Int) -> Int {
> if b == 0 {
> let n: Never = fatalError()
> return n as Int
> }
> return a / b
> }
>
> I pushed the idea of replacing rethrows with Never, inspired by Haskell.
> Although Haskell doesn’t have static function requirements and initializer
> requirements.
>
>
> Thanks for the links.  I scanned through them somewhat quickly and didn’t
> see anything that specifically said `Never` should conform to all
> protocols.  Did you see that specifically?  I only saw mentions of it being
> a bottom type and therefore a subtype of all types, which I think is a bit
> different.
>
> I think a big part of the confusion here revolves around the distinction
> between a type `T` being a subtype of another type `U` and `Type` being
> a subtype of `Type` (using the 

Re: [swift-evolution] [Proposal] Typed throws

2017-02-20 Thread Anton Zhilin via swift-evolution
I messed up with links a little bit, duplicating one of them. Here

is another one.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Typed throws

2017-02-20 Thread Anton Zhilin via swift-evolution
2017-02-20 18:23 GMT+03:00 Matthew Johnson :


> On Feb 20, 2017, at 3:58 AM, Anton Zhilin  wrote:
>
> But that raises another concern. In a previous discussion, it was taken
> for granted that Never should conform to all protocols
>
> Do you have a pointer to this discussion?  I must have missed it.
>
Here

is the discussion where the idea of “empty” type originated.
Some messages on the topic ended up being there
.

This  is the
earliest mention of usage of this empty type for rethrows I could find.
Some related messages are here

as well.

We called this type NoReturn and meant it to be the *bottom type*, i.e.
subtype of all types, meaning that if you have an instance of NoReturn—which
can only happen in unreachable sections of code—then you can convert it to
any type. It should have worked like this:

func fatalError() -> Never

func divide(a: Int, b: Int) -> Int {
if b == 0 {
let n: Never = fatalError()
return n as Int
}
return a / b
}

I pushed the idea of replacing rethrows with Never, inspired by Haskell.
Although Haskell doesn’t have static function requirements and initializer
requirements.

, because if one obtains an instance of Never (and they won’t), then
> everything is possible. But now we say that Never can’t conform to Default,
> because this would break its very invariant. Also it can’t conform to any
> protocol with static members or initializers.
>
> It seems highly problematic to me to say that never conforms to any
> protocol with non-instance requirements.
>
Here is an example with instance requirements only:

protocol MakesPizza {
func cook() -> Pizza
}
extension Never : MakesPizza {
func cook() -> Pizza {
// this method will never be called anyway
burnThisComputer()
}
}

let maestroLaPizza = isHeAtWork ? validMaestro :
(fatalError("something went wrong") as MakesPizza)
maestroLaPizza.cook()

In this way, Never can conform to any protocol with only instance
requirements.

But then basically, Never trick can’t be used when we request anything more
> than Error from generic error type (with static members or initializers).
> So this approach turns out to be more limiting than rethrows.
>
> Can you elaborate here?  If you require a function to throw an error type
> that has non-instance requirements then you would necessarily be
> restricting callers to provide a throwing function.  It is not possible to
> express such a function with `rethrows`.  You can’t talk about the error
> type at all.  If you could talk about the error type and were able to
> constrain it in this way `rethrows` would necessarily have to exhibit the
> same behavior as the generic version.  The behavior arises out of the
> constraint you are applying, not the mechanism by which you forward the
> type.
>
With rethrows approach:

protocol BaseError : Error {
init()
}

func seq(f: () throws(E1) -> (), g: () throws(E2) -> ())
rethrows(BaseError)
 where E1: BaseError, E2: BaseError { ... }

With Never approach, we have to create two separate functions for the same
effect, because Never does not fit in BaseError:

func seq(f: () throws(E1) -> (), g: () throws(E2) -> ())
throws(BaseError)
 where E1: BaseError, E2: BaseError {
// It never actually throws E1() or E2() itself, but this fact
can't be reflected in the signature
}

func seq(f: () -> (), g: () -> ()) {
// repeat the body
}

That’s where loss of information (which I meantioned earlier) hurts: we
can’t apply magic and say “if E1 and E2 are Never then seq does not throw.
Because it *can* throw anyway.

Well, I’m just repeating myself, at least I gave a bit more complete
example :)
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Typed throws

2017-02-20 Thread Anton Zhilin via swift-evolution
2017-02-19 23:29 GMT+03:00 Matthew Johnson :

Thanks.  There is nothing wrong with this at all.  Your second `exec` would
> not accept a non-throwing function because `Never` cannot conform to
> `Default`.  If it didn’t include the `Default` constraint it would not be
> able to `throw E()`.
>
But that raises another concern. In a previous discussion, it was taken for
granted that Never should conform to all protocols, because if one obtains
an instance of Never (and they won’t), then everything is possible. But now
we say that Never can’t conform to Default, because this would break its
very invariant. Also it can’t conform to any protocol with static members
or initializers.

But then basically, Never trick can’t be used when we request anything more
than Error from generic error type (with static members or initializers).
So this approach turns out to be more limiting than rethrows.
Don’t misunderstand me—I love the idea of Never replacing rethrows. Just
want to make sure we don’t lose anything important by the way.

If you remove the `Default` constraint and change `throws(E)` to `throws`,
> and throw `MyError()` in place of `E()` in both places then it behaves
> exactly as the first example. We don’t lose any expressivity at all.
>
> This is actually an example of a strength of Joe’s suggestion: the second
> `exec` is able to throw an error of a type that matches the error that
> might be thrown by the calling argument `f`.  I’m not sure of where this
> might be useful but it is definitely not possible with `rethrows` while it
> is possible with Joe’s proposal.  We have more flexibility in API design
> under Joe’s proposal.
>
Nice. Whether we can throw the error ourselves depends on our ability to
create the error.

You did make a great point about coalescing error types from several
> different function arguments.  That’s an edge case, but the inability to
> coalesce is indeed a problem that probably needs to be addressed by the
> typed throws proposal in one way or another (if we don’t go with Joe’s
> suggestion we would need to specify how `rethrows` behaves in cases like
> this in some detail).
>
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Typed throws

2017-02-19 Thread Anton Zhilin via swift-evolution
2017-02-19 22:59 GMT+03:00 Matthew Johnson :

On Feb 19, 2017, at 1:32 PM, Anton Zhilin  wrote:
>
> Now that I think about it, generic throws does not exactly cover rethrows.
> Firstly, rethrows has semantic information that function itself does not
> throw—it would be lost.
>
> Can you elaborate further on what you mean by this?
>
protocol Default { init() }

func exec(f: () throws -> Void) rethrows
{
try f()
throw MyError()  // error because of rethrows
}

func exec(f: () throws(E) -> Void) throws(E)
 where E: Error & Default
{
try f()
throw E()  // okay
}

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


Re: [swift-evolution] [Pitch] Typed throws

2017-02-19 Thread Anton Zhilin via swift-evolution
It’s expected that if you need resilience, then you will throw an “open”
enum. Essentially, we pass resilience of typed throws on to those who will
hopefully establish resilience of enums.

If you prefer separate error types, then declare a base protocol for all
your error types and throw a protocol existential. You won’t even need
default case in switches, if closed protocols make it into the language.

I don’t like any solution that is based on comments. I think that compiler
should always ignore comments.

2017-02-18 18:27 GMT+03:00 Karl Wagner :


> So, I’m not sure about what was decided last time, but my issues with this
> are:
>
> - The thrown error type will become part of the ABI of the function. If
> you change the type of Error that is thrown, callers may not catch it. At
> the same time, if we make enums resilient by default and only allow
> specifying a single entire type, you will basically need one Error enum per
> function and it will need to be @fixed if you actually want to remove the
> catch-all block. Otherwise:
>
> // Let’s say this isn’t @fixed...
>
> enum CanFailError {
> errorOne
> errorTwo
> }
>
> func canFail() throws(CanFailError) { /* … */ }
>
> do { try canFail() }
> catch CanFailError {
> switch error {
> case .errorOne: /* handle error one */
> case .errorTwo: /* handle error two */
> default:/* handle possible new errors in later versions of
> the library */
> }
> }
>
> do { try canFail() }
> catch .errorOne { /* handle error one */ }
> catch .errorTwo { /* handle error two */  }
> catch   { /* handle possible new errors in later versions of the
> library */ }
>
> - I usually have _semantic_ namespaces for Errors, rather than single
> types per implementation pattern. If we are adding strong annotations about
> which errors can be thrown, I’d quite like to incorporate that pattern. For
> example:
>
> extension File {
>
> @fixed enum OpeningError {
>
> case .invalidPath
> case .accessDenied  // e.g. asking for write permissions for read-only file
>
> }
> @fixed enum ReadError {
>
> case .invalidOffset // past EOF
> case .deviceError   // probably worth aborting the entire operation the
> read is part of
>
> }
>
> // - throws:
> // - .OpeningError if the file can’t be opened
> // - .ReadError if the read operation fails
> func read(from offset: Int, into buffer: UnsafeBufferPointer)
> throws(OpeningError, ReadError) { /* … */ }
>
> }
>
>
> - I wonder if we could try something more ambitious. Since the list of
> thrown errors is resilience-breaking for the function, it is only
> beneficial for versioned and @inlineable functions. They should not be able
> to add new errors (they can remove them though, since errors are intended
> to be switched over). I wonder if we couldn’t introduce a small pattern
> grammar for our structured comments (isolated from the rest of the
> language) - it would be optional, but if you do list your errors, the
> compiler would validate that you do it exhaustively. Some patterns I would
> like are:
>
> // - throws: - MyError.{errorOne, errorThree, errorFive}: Something bad
>|| considered exhaustive
> @inlineable public func canFail() throws {}
>
> // - throws: - OpeningError: Computer says no... || considered
> exhaustive if OpeningError is versioned or @fixed
> //   - * || other errors,
> requires “catch-all” by external callers
> @inlineable public func canFail2() throws {}
>
> If we want to get really clever, we can have the compiler automatically
> generate those error-lists for internal functions, so you would
> automatically get exhaustive error-handling within your own module.
>
> - Karl
>
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Typed throws

2017-02-19 Thread Anton Zhilin via swift-evolution
2017-02-19 0:16 GMT+03:00 Martin Waitz :
>
> Now some bike-shedding:
> I’m not really happy with the `throws(Type)` syntax, as it is too close to
> function parameters.
> Why exactly is `throws Type` ambiguous?
> The proposal mentions `Type -> Result` as potential thrown type, but
> functions cannot conform to `Error`.
>

Well, it's expected to change with one of the follow-up proposals.


> Maybe we can instruct the parser to just allow simple type names between
> `throws` and the arrow `->`.
>

The ambiguity here is not so "to compiler" as "to human". We don't want
people to spend extra time parsing the declaration.

If that is not possible, we should at least try to find some visual hints
> to separate Error type from function parameters.
>
> E.g. we could use brackets (think of: we are specialising the `throws`):
>
> func foo() throws { … }
>

 I personally prefer parentheses, because there is precedence of
parametrized attributes. I wonder what others think on angle brackets
option.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Typed throws

2017-02-19 Thread Anton Zhilin via swift-evolution
Now that I think about it, generic throws does not exactly cover rethrows.
Firstly, rethrows has semantic information that function itself does not
throw—it would be lost.

Secondly, rethrows allows a function with multiple throwing function
parameters to become non-throwing iff all the arguments are non-throwing.
How would you express it with generics?
In the proposal, in this case you are required to provide a non-generic
supertype of all used error types. This type can’t just turn into Never
automatically.

One solution would be to retain rethrows as an additional attribute.
It would help with semantic information, and resulting error will be able
to turn into Never as a special case—now that we know, that this function
doesn’t throw that error itself.

2017-02-19 0:16 GMT+03:00 Martin Waitz :


> Am 18.02.2017 um 17:37 schrieb Matthew Johnson via swift-evolution <
> swift-evolution@swift.org>:
>
> Thank you for taking the time to put this proposal together Anton!  I
> really want to see typed throws make it into Swift 4.  This will be a very
> nice feature to have.
>
> I noticed that you included Joe Groff’s idea of replacing `rethrows` by
> making every function have an error type which is by default `Never` for
> non-throwing functions and `Error` for throwing functions that do not
> specify an error type.
>
> I want to urge you to consider updating the proposal to take this
> direction now rather than later.  This is a breaking change which means the
> longer we wait the harder it is to justify.  In fact, I think incorporating
> the breaking change could increase the chances of it being accepted for
> Swift 4.  Without that it is a purely additive change and those are not
> being given priority in the Swift 4 release.
>
>
> Seconded.
> With typed throwing function parameters, it makes a lot of sense to be
> able to specify the rethrown type, based on the function given as parameter.
>
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Refactor Metatypes

2017-02-18 Thread Anton Zhilin via swift-evolution
Type is a bad name for a public type: FooType is almost always a better
name. Libraries that describe “just types”, Swift types, can as well use
Metatype or Mirror or something.
For nested types, like Foo.Type, in the meaning of “type of Foo“, Type
can’t be used even now.
I’d give up on Type name for the greater future of metatypes.

2017-02-18 16:28 GMT+03:00 Adrian Zubarev :

Personally I’d prefer Metatype and AnyMetatype to get rid of the
> restriction where you mostly cannot create custom types called Type,
> which annoys me a lot. Sometimes Kind as a good workaround but there are
> times where Kind doesn’t fit. :/
>
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [Proposal] Typed throws

2017-02-18 Thread Anton Zhilin via swift-evolution
I’ve created a proposal draft, copy-pasting some parts from David Owens’
proposal.
Here it is 
.

I had to make one addition, which hasn’t been discussed yet. Look at Multiple
throwing calls

section. Is this feature controversal, or it’s fine to keep in the
proposal? Is it feasible from implementation point of view?
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Typed throws

2017-02-17 Thread Anton Zhilin via swift-evolution
Several proposals will follow this one: allowing multiple error types,
removing Error, replacing rethrows, etc.
Those topics are more controversial, but fortunately for them, they mostly
add on top of the core feature being discussed.
So IMO, if a detail can be split into its own proposal, we should just do
it and forget about it for a little while.

2017-02-17 23:16 GMT+03:00 Tino Heth <2...@gmx.de>:


> I thought it was going to be any one subtype of Error, be it a struct, an
> enum, or a protocol existential, or Error itself.
>
>
> Imho we should remove the restriction that you can only throw
> Error-conforming types if typed throws are added:
> It's a compatibility feature, and if you manually declare what can be
> thrown, you should be allowed to break with Objective-C.
>
> As Error has no requirements at all, it looks like harassment, as its
> whole magic is neither visible nor necessary.
>
> ​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Typed throws

2017-02-17 Thread Anton Zhilin via swift-evolution
In this case, you’d better create a new error type, which includes all the
cases of those errors:

// FileNotFoundError and WrongFormat are Error-s

struct PreferencesError : Error {
init(_: FileNotFoundError)
init(_: WrongFormat)
// ...
}

func readPreferences() throws(PreferencesError)

In the most “lazy” case, you’d just create an enum of those two:

enum PreferencesError : Error {
case fileNotFound(FileNotFoundError)
case wrongFormat(WrongFormatError)
}

Better yet, you should analyze, which cases are meaningful for user of
readPreferences, and present them with appropriate interface. You may want
to crash on those cases of initial error types, with which you can’t do
anything on the level of abstraction of readPreferences. Some of the others
will be merged or renamed.

With proper error types, a single type in throws clause is enough, without
sum types.

2017-02-17 22:22 GMT+03:00 Adrian Zubarev via swift-evolution <
swift-evolution@swift.org>:

Sure thing, but that’s not what I was asking about. Kevin made a protocol
> that conforms to Error where all the his enums conformed to MyError
> protocol. That way we’re losing all enum cases and are not really a step
> further as before.
>
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Typed throws

2017-02-17 Thread Anton Zhilin via swift-evolution
2017-02-17 22:12 GMT+03:00 Adrian Zubarev via swift-evolution <
swift-evolution@swift.org>:

Is the throwing type always a protocol? In your example it is, but is this
> going to be always the case?
>
I thought it was going to be any one subtype of Error, be it a struct, an
enum, or a protocol existential, or Error itself.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [Pitch] Typed throws

2017-02-17 Thread Anton Zhilin via swift-evolution
Now this is on-topic, I guess.
Last time we stopped at John McCall’s syntax:

extension MyError: Error { ... }

func foo() throws(MyError) -> MyResult

It’s conservative and prevents visual ambiguity with extra parentheses.

If we (somewhat) agree on this, then submitting a proposal will be trivial.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Support for pure functions. Part n + 1.

2017-02-17 Thread Anton Zhilin via swift-evolution
Just let

@pure func foo(_ f: (Int) -> Int) -> Int

be the same as those two combined:

@pure func foo(_ f: @pure (Int) -> Int) -> Int
func foo(_ f: (Int) -> Int) -> Int

No need for anything like “re-pure” or ≃>.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Support for pure functions. Part n + 1.

2017-02-17 Thread Anton Zhilin via swift-evolution
I didn’t mean to emphasize any specific syntax. I’m fine with either @const,
@constexpr, @pure or =>.
Anyway, I see no reason why generic functions shouldn’t be supported in any
of the suggested models.

2017-02-17 19:08 GMT+03:00 Abe Schneider :

+1. I think this is a great idea. As I was following this thread, I
> was wondering if someone might suggest the C++ constexpr syntax.
>
> Would this support generics? E.g. could you do:
>
> @constepxr
> func foo(a:S, b:S) {
>return a+b
> }
>
> and have that be done at compile time? While this could potentially
> add a huge amount of complication on the backend, I could this as
> being useful (also related to my previous postings as to having a way
> of determining generic types at compile time).
>
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Support for pure functions. Part n + 1.

2017-02-17 Thread Anton Zhilin via swift-evolution
2017-02-17 17:13 GMT+03:00 T.J. Usiyan :

It is my opinion that you are describing an entirely different, and
> somewhat orthogonal, feature. I would like the feature that you describe.
> Constant expressions are powerful and open up quite a few optimizations.
> What constexpr addresses is not purity, at the heart of it. Pure
> expressions that accept compile-time-known values are, by happy accident,
> compile-time-computable, but pure expressions that accept dynamic values
> are not. Conflating the two qualities of being compile-time-known and being
> pure within the same keyword and overloading it in this way is not
> desirable to me.
>
I see now. I’d say that access to global state is not vital, and @pure
functions are more useful than @const functions, so I’m OK with having only
@const functions.

To control growth of compilation time, we could have both @pure function
annotation and @const variable annotation to *ensure* that a @pure
expression is computed at compilation time.

I’d also want to infer @pure whenever possible, but is it possible with
functions in different modules?
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Refactor Metatypes

2017-02-17 Thread Anton Zhilin via swift-evolution
I guess, now is the time? The response on this has been positive, both for
the new metatype syntax and separation of static and dynamic metatypes.

I’ve got one more feature in mind since then—a shorthand of AnyType ≡
AnyType.
Would this addition be worth extra syntax? Is it feasible from current
generics point of view? Anyway, it can be done in a separate proposal.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Support for pure functions. Part n + 1.

2017-02-17 Thread Anton Zhilin via swift-evolution
My vision of “pure” functions was the following:

   1. Compiler automatically marks all functions and expressions as pure,
   wherever possible
  - We should be interested not in “Haskell-ish pure” functions, but in
  “computable during compilation” functions
  - Therefore I prefer to use @constexpr or const instead of @pure
   2. We can mark a function as const to *assert* that it is indeed pure
   3. We can mark a variable as const to *ensure* that it’s computed at
   compilation time
  - Compiler might compute some non-const expressions, but no
  guarantees given

One issue is, we don’t have or suggest any facilities to make use of pure
functions, other than some optimization, which can be performed anyway as
of now.

One use-case would be conversion of metatypes to types:

const let x: Any = makeSomething()
typealias T = type(of: x)

This feature can be powerful enough to fill the niche of macros in Swift,
without unsafety of C++ or specific syntax of Rust.

2017-02-17 14:14 GMT+03:00 Haravikk via swift-evolution <
swift-evolution@swift.org>:

I like the idea of having pure functions in Swift, but my first thought is;
> should we have to declare it at all? Is it not easier to just have the
> compiler automatically flag a function as pure or not?
>
> With that in mind we don't need any new syntax, but a simple @pure
> attribute should be sufficient. This can be used anywhere that a function
> is declared, or a closure is accepted as a parameter, allowing us to be
> explicit that we are trying to define a pure function, or only accept pure
> closures.
>
> The big benefit of this is that it is retroactive; all existing functions
> that are pure will be automatically detected as such, and can be passed
> into any method accepting only pure functions. The new capability will be
> that developers can specify that a function *must* be pure and thus produce
> an error if it isn't.
>
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] array splatting for variadic parameters

2017-02-14 Thread Anton Zhilin via swift-evolution
2017-02-14 18:32 GMT+03:00 Dimitri Racordon via swift-evolution <
swift-evolution@swift.org>:

The proposal is indeed really interesting.
> I would love to see if it could get a second round of discussion.
>
> However, I failed to understand the syntax of the proposed extension.
> Where would be defined the label and parameter names? Is this just a typo?
>
> func someFunc
> “Obviously”, the Collection variant should look like:

func someFunc(_ values:
@variadic C) { … }

And the others are analagous.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] for in? optionalCollection {

2017-02-11 Thread Anton Zhilin via swift-evolution
for i in test ?? [] {
print(i)
}

For a more general solution, we could add Optional.flatten() to support
optional sequences:

for i in test.flatten() {
print(i)
}

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


Re: [swift-evolution] Overriding protocol default implementation

2017-02-10 Thread Anton Zhilin via swift-evolution
I’d even suggest to force final for such methods:

protocol Fooable { }
extension Fooable {//  func foo() { }// error: must be declared as final
final func foo() { }  // ok
}

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


Re: [swift-evolution] !? operator for ternary conditional unwrapping

2017-02-08 Thread Anton Zhilin via swift-evolution
With Runes , this looks like:

(name1 <^> { "\"\($0)\"" }) ?? "null"

Runes defines <^> to have lower precedence than ??. Sadly, they all can’t
be in the same precedence group due to right associativity of ??.

2017-02-08 18:11 GMT+03:00 Tony Allevato via swift-evolution <
swift-evolution@swift.org>:

What you're asking for is already possible (avoiding the optional unwrap)
> by combining map() on Optional with ??:
>
> ```
> let name1: String? = "name"
> print(name1.map { "\"\($0)\"" } ?? "null")  // prints "\"name\""
>
> let name2: String? = nil
> print(name2.map { "\"\($0)\"" } ?? "null")  // prints "null"
> ```
>
> So I guess the question is, does simplifying that rise to the level of
> wanting a custom operator? I personally don't think it does, but I could
> see an argument being made that an operator with defined semantics might be
> a small amount clearer than map + ??. But I think the benefits would have
> to be very strong, though.
>
> And as other folks have mentioned, having "!" in the operator name is
> somewhat misleading, since when I see that I expect a trap to occur in nil
> cases.
>
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Checking in; more thoughts on arrays and variadic generics

2017-02-06 Thread Anton Zhilin via swift-evolution
2017-02-06 15:35 GMT+03:00 Tino Heth via swift-evolution <
swift-evolution@swift.org>:

> Consider even if we had compile-time constants like Vector —
> how would that be implemented? What would its backing-type be?
>
> Imho it's very simple — UnsafeMutableBufferPointer would be an obvious
> choice.
>

And then we just have an Array with static size guarantee. But to solve
the import story and gain space for optimization, we need stack-storage
arrays.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] for-else syntax

2017-02-01 Thread Anton Zhilin via swift-evolution
You can write a helper method that adds a placeholder if the array is empty:

for name in names.placeholder("no names") {
print(name)
}

Implementation:

extension Collection {
func placeholder(_ elem: Iterator.Element) -> PlaceholderView
{
return PlaceholderView(collection: self, ifEmpty: elem)
}
}

enum PlaceholderView : Collection {
case original(C)
case placeholder(C.Iterator.Element)

init(collection: C, ifEmpty: C.Iterator.Element) {
if (collection.isEmpty) {
self = .placeholder(ifEmpty)
} else {
self = .original(collection)
}
}

// implement Collection conformance
}

2017-02-01 19:48 GMT+03:00 Chris Davis via swift-evolution <
swift-evolution@swift.org>:

> Hi,
>
> Often when I’m programming I stumble upon this scenario:
>
> I have a list of items that may or may not be empty - if it’s full, I do
> one thing, if it’s empty I do something else, my code looks like this:
>
> class Example_1
> {
> let names = ["Chris", "John", "Jordan"]
>
>
> /// Loop over names, if no names, print no names
> func run()
> {
> for name in names
> {
> print(name)
> }
>
>
> if names.count == 0
> {
> print("no names")
> }
> }
> }
>
> let exampleOne = Example_1()
> exampleOne.run()
>
> However, Personally, I would find it more pleasing to write something like
> this:
>
> class Example_2_Proposed
> {
> let names:[String] = []
>
>
> /// Loop over names, if no names, print no names
> func run()
> {
> for name in names
> {
> print(name)
> } else {
> print("no names")
> }
> }
> }
>
> let exampleTwo = Example_2_Proposed()
> exampleTwo.run()
>
> The difference here is a “for-else” type syntax where if there were no
> items in the array it would simply fall through to the else statement.
>
> What would be the pros/cons of introducing such syntax?
>
> Is there’s a way of doing something similar in swift already?
>
> Thanks
>
> 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] Default Generic Arguments

2017-01-27 Thread Anton Zhilin via swift-evolution
Current alternative to default generic arguments is typealias, like
basic_string and string in C++:

struct BasicBigInt { ... }
typealias BigInt = BasicBigInt

It’s not *that* ugly. It keeps type inference rules simpler, easier to
understand and more explicit.
As someone noted, current type inference for generic initializers works
satisfactory in 99% cases. Is it really worth it to try to cover 99.9% at
the cost of complexity of type inference rules?

On the other hand, in the wild, there may exist types with 3 or even more
generic parameters that have sensible default values. [Research needed]
For such complex cases, I think, it makes sense to add default generic
parameters *only* together with generic parameter labels.
Also, in such cases, functions on types could often help. And that story is
even out of scope of Swift 4 Phase 2.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Testing enum cases with associated values

2017-01-18 Thread Anton Zhilin via swift-evolution
AFAICS, Andy needs not default implementations of Equatable, but
cases-as-optional-properties—this topic has also been discussed on the list.

enum Result {
case success(Int)
case failure(String)
}

let r: Result = foo()

let x: Int? = r.success
let y: String? = r.failure

assert(r.success == Optional(42))
assert(r.failure == nil)

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


Re: [swift-evolution] Will existentials ever conform to their protocols?

2017-01-18 Thread Anton Zhilin via swift-evolution
There is also a caveat with static members:

protocol P {
static func foo()
}

struct S : P {
static func foo() { }
}

func bar(x: T) {
T.foo()
}

let p = S() as P
bar(p)  // P.foo() does not exist

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


Re: [swift-evolution] Reduce with inout

2017-01-18 Thread Anton Zhilin via swift-evolution
While realizing that this name can cause confusion, I'd still prefer
`reduce(mutating:_:)`, because it looks like the only readable option to me.
Whatever name will be picked, I agree that traditional reduce without
mutation should retain its name.

2017-01-18 5:17 GMT+03:00 Xiaodi Wu via swift-evolution <
swift-evolution@swift.org>:

> A serious possibility would be: `reduce(mutableCopyOf: x) { ... }`.
>
> It's verbose, but the nicer-looking `reduce(mutating: x) { ... }` is
> incorrect since, as Charles pointed out to Dave, it's not `x` that's
> mutated but rather a mutable copy of it, so it doesn't matter if `x` itself
> is declared with `let` or `var`.
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Fixing raw enum types

2017-01-17 Thread Anton Zhilin via swift-evolution
2017-01-17 22:26 GMT+03:00 Joe Groff :

> enum Something : RawRepresentable
> +1. But we don’t have generic protocols right now :(
>
> I think this would be the right direction to go if we wanted to de-magic
> the existing RawRepresentable behavior. At this point, It would be
> reasonable to support this via where clauses on associated types:
>
> enum Something: RawRepresentable where RawValue == Int32 { ... }
>
>
We don't have this conformance syntax either. As the enum is not generic,
the above should be read as:

enum Something: (RawRepresentable where RawValue == Int32) { ... }

And this requires generalized existentials again.

though that's pretty verbose. In the fullness of time, a generic typealias
> to a generalized existential could help with that, though:
>
> typealias RawRepresentableOf = RawRepresentable where RawValue == T
>
>
> At that point, the compiler-built becomes closer to just a "regular"
> default implementation. There's still the privileged sugar for matching
> cases to raw values.
>
> -Joe
>
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Fixing raw enum types

2017-01-17 Thread Anton Zhilin via swift-evolution
Some criticism for all the mentioned variants:

enum Something : raw(Int32)
Requires adding a new contextual keyword.

enum Something : RawRepresentable
With additional typealias RawValue, the simplest cases will lose their
elegancy.

enum Something : RawRepresentable
+1. But we don’t have generic protocols right now :(

enum Something
-1. This way we would just trade overloading conformance syntax for
overloading generics syntax.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Fixing raw enum types

2017-01-16 Thread Anton Zhilin via swift-evolution
This idea by Karl made me branch off a new thread.

2017-01-16 21:28 GMT+03:00 Karl Wagner :

It would be helpful for synthesised RawRep conformance. The
> inheritance-like syntax we have now is awful - it makes people think that
> RawRepresentable is some kind of magic protocol that will allow special
> compiler jango to happen.
>
> You could see why they think that. This looks very much like the enum is
> going to *be* an Int32:
>
> enum Something: Int32 {
> case oneThing = 36
> case anotherThing = 42
> }
>
> This is also one of the icky parts to allowing tuples of integer/string
> literals (something people ask for quite a lot). It would look like you’re
> deriving your enum from a non-nominal type:
>
> enum Something: (Int32, Int32) {
> case oneThing = (3, 12)
> case anotherThing = (5, 9)
> }
>
> Even if Swift gains newtype, it’s not that case. The enum does not gain
methods or behavior of the specified type. It’s just a shorthand, hinting
the compiler to provide correct RawRepresentable conformance.

I suggest to invent a new syntax for this type hinting for RawRepresentable.
For example, it can be an annotation:

@raw(Int32) enum Something {
// ...
}

Or a contextual keyword:

enum Something : raw(Int32) {
// ...
}

Perhaps, he most uniform and explicit of syntaxes:

enum Something : RawRepresentable {
case oneThing = 36
case anotherThing = 42
}

enum AnotherThing : RawRepresentable {
typealias RawValue = Int32
case oneThing
case anotherThing
}

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


Re: [swift-evolution] protocol-oriented integers (take 2)

2017-01-15 Thread Anton Zhilin via swift-evolution
What about taking a mathematical approach to numbers?

protocol Group : Equatable {
static var zero: Self { get }
static func + (Self, Self) -> Self
static func += (inout Self, Self)
static func - (Self, Self) -> Self
static func -= (inout Self, Self)
static prefix func - (Self) -> Self
}

protocol Ring : Group {
static var one: Self { get }
static func * (Self, Self) -> Self
static func *= (inout Self, Self)
func tryDivide(by: Self) -> Self?
func tryInvert() -> Self?
}

protocol Field : Ring {
static func / (Self, Self) -> Self
static func /= (inout Self, Self)
var inverted: Self { get }
}

protocol VectorSpace : Group {
associatedtype Scalar : Field
static func * (Self, Scalar) -> Self
static func *= (inout Self, Scalar) -> Self
static func / (Self, Scalar) -> Self
static func /= (inout Self, Scalar) -> Self
static func * (Scalar, Self) -> Self
}

Detalization of mathematical terminology will be determined by what kind of
types we have in the standard library. Integer types are rings (except for
overflow), floating-point types are fields (except for precision), point
types are linear spaces, so I thought the abstractions above are the bare
minimum.

Unfortunately, Swift doesn’t have rename operations for protocol
requirements, so we can’t express groups that use operations other than +
and -. What we can do is to include an adapter to wrap current instance in
an additive group interface:

struct MultiplicativeGroupAdapter : Group {
// ...
}

extension Field {
var multiplicativeGroup: MultiplicativeGroupAdapter
}

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


Re: [swift-evolution] Generic Subscripts

2017-01-14 Thread Anton Zhilin via swift-evolution
I’m not sure, but I think that in this case the specific type of these
values is determined at runtime.
Then a safe approach would be separate string: String?, bool: Bool?, int:
Int? computed properties, as it’s done in JSON parsers.

if let bookCount = row.value(named: "bookCount").int {
...
}
if let bookCount = row["bookCount"].int {
...
}
let bookCount = row.int("bookCount")!   // crash if database is corrupt

Additionally, this is an overall bad example of generics. Fields of
database tables can only map to a limited set of static types in Swift,
which are supported by database adapter.

2017-01-14 16:50 GMT+03:00 Gwendal Roué via swift-evolution <
swift-evolution@swift.org>:

This is a consequence of your vision of subscript. If interesting, it is
> also limiting for no real purpose.
>
> As the developer of a Swift database library, I'd like to offer a better
> API than the following:
>
> // Current state of affairs
> let name: String = row.value(named: "name")
> let bookCount: Int = row.value(named: "bookCount")
> let hasBooks: Bool = row.value(named: "bookCount")
>
> Instead, I wish I could offer GRDB.swift would let its users write:
>
> // With improved subscripts
> let name: String = row["name"]
> let bookCount: Int = row["bookCount"]
> let hasBooks: Bool = row["bookCount"]
>
> And this requires genericity on return type.
>
> Gwendal
>
>
> ___
> 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] Equatability for enums with associated values

2017-01-13 Thread Anton Zhilin via swift-evolution
That seems pretty close to Rust’s derive. Why not invent a similar syntax
in Swift? Otherwise it will make us look through all the sources to make
sure deriving is used.

enum Option: @derive Equatable {
...
}

Also, we can get better looking compilation errors, like:

ERROR at line 1, col 14: could not derive Equatable for Option
enum Option: @derive Equatable {
 ^

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


Re: [swift-evolution] Consolidate Code for Each Case in Enum

2017-01-12 Thread Anton Zhilin via swift-evolution
2017-01-12 0:51 GMT+03:00 David Sweeris :
>
> I don't understand the lines in the struct version where you assign
> something to `self`. What is ".invalid", for example? I thought you'd
> removed the enum altogether.
>

I totally overlooked it. That can't be done with protocols, scrap that
suggestion.

> But pattern matching on structs is impossible—we can change that with a
> separate proposal. For example, we can allow destructuring
> structs/enums/classes by any combination of their properties:
>
> struct S {
> var foo: Int
> var bar: Double
> var buz: String { return "42" }
> }
> let s = S(foo: 42, bar: 42.0)
> let S(foo: x, buz: z) = s
>
> I was under the impression that we could switch over anything that had the
> `~=` operator defined. Is that not the case?
>

Well, this one is a bit different, but it's horribly off-topic for this
thread.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Consolidate Code for Each Case in Enum

2017-01-11 Thread Anton Zhilin via swift-evolution
Wouldn’t protocols be a better solution in this case? If little to no logic
can be shared between enum cases, why have the enum in the first place?

Your variant:

protocol State {

mutating func react(to event: Event)
}
enum AuthenticationState: State, CustomStringConvertible {

case invalid {
var description: String { return "Authentication invalid." }

mutating func react(to event: Event) {
switch event {

case let login as UserLoggedIn:
self = .validated(token: login.token)
default:
break
}
}
}

case expired(_ expiration: Date) {
var description: String { return "Authentication expired at
\(expiration)." }

mutating func react(to event: Event) {
switch event {
case let refreshed as TokenRefreshed:

self = .validated(token: refreshed.token)

default:
break
}
}
}

case validated(token: String) {

var description: String { return "The authentication token is
\(token)." }

mutating func react(to event: Event) {
switch event {

case let expiration as TokenExpired:
print("Expiring token: \(token)")
self = .expired(expiration.date)
case _ as TokenRejected:
self = .invalid
case _ as UserLoggedOut:
self = .invalid
default:
break
}
}
}

}

My suggestion:

public protocol State {

mutating func react(to event: Event)
}

@closed protocol AuthenticationState : State, CustomStringConvertible { }
struct InvalidAuthenticationState : AuthenticationState {
var description: String { return "Authentication invalid." }

mutating func react(to event: Event) {
switch event {

case let login as UserLoggedIn:
self = .validated(token: login.token)
default:
break
}
}
}
struct ExpiredAuthenticationState : AuthenticationState {
var expiration: Date

var description: String { return "Authentication expired at
\(expiration)." }

mutating func react(to event: Event) {
switch event {
case let refreshed as TokenRefreshed:

self = .validated(token: refreshed.token)

default:
break
}
}
}
struct ValidatedAuthenticationState : AuthenticationState {
var token: String

var description: String { return "The authentication token is \(token)." }

mutating func react(to event: Event) {
switch event {

case let expiration as TokenExpired:
print("Expiring token: \(token)")
self = .expired(expiration.date)
case _ as TokenRejected:
self = .invalid
case _ as UserLoggedOut:
self = .invalid
default:
break
}
}
}

If AuthenticationState is not public, then compiler can make an
optimization and turn existentials and indirect calls into an enum,
essentially.
We can even split public protocols into open and public, as we did with
classes, to allow for expressing this intent more explicitly.

But pattern matching on structs is impossible—we can change that with a
separate proposal. For example, we can allow destructuring
structs/enums/classes by any combination of their properties:

struct S {
var foo: Int
var bar: Double
var buz: String { return "42" }
}
let s = S(foo: 42, bar: 42.0)
let S(foo: x, buz: z) = s

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


Re: [swift-evolution] Move placement of 'throws' statement

2017-01-09 Thread Anton Zhilin via swift-evolution
I also thought about sum types as implementation of errors, but selecting
between Tyler’s and John’s syntaxes, I would pick the latter. Compare:

let x: (_ a: Int) -> (Error | (_ b: Float) -> (Error | Double))
let x: (_ a: Int) throws(Error) -> (_ b: Float) throws(Error) -> Double
let x: (_ a: Int) -> (Error | Double)
let x: (_ a: Int) throws(Error) -> Double

Granted, the version with sum types contains less characters and leads to
more minimalistic type system. But | on itself does not mean error
handling. It’s used for creation of sum types, without error handling
semantics. So it’s easier to grasp the meaning of type containing throws
than anything else. If Swift had a special symbol as related to errors, as ?
relates to optionals, then we could use it there. Unfortunately, there
isn’t anything like that.

What would it look like if the function returns nothing but can throw an
error?

let x: (_ a: Int) -> (Error | ())

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


Re: [swift-evolution] [Proposal draft] Use obtain let instead if let construction

2017-01-08 Thread Anton Zhilin via swift-evolution
-1 to obtain, unwrap and such.
+1 to removing optional pattern in favor of normal if-pattern, plus
removing case:

if let unwrapped? = optionalValue { ... }

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


Re: [swift-evolution] [Pitch] Tweak `Self` and introduce `Current`

2017-01-07 Thread Anton Zhilin via swift-evolution
I have no problem with the syntax proposed in SE-0068.
The rationale briefly mentions that dynamic Self will be used anywhere
inside the class body. I think that the possibilities that open with this
decision should be mentioned in the proposal.

We can say that non-final classes, apart from that they can also have
instances of themselves, behave very much like protocol existentials. They
couple requirements and “default implementation”. Like existential
protocols, they can’t have associated types. SE-0068 expands abilities of
classes and allows their requirements to contain Self. “Default”
implementation is mandatory, as usual. Example of code that will be
possible:

// Compiles now

protocol P {
init()
func foo(_ x: Self) -> Self
}

extension P {
func foo(_ x: Self) -> Self {
print(Self.self)
return Self.init()
}
}

struct S : P { }

let x = S()
_ = x.foo(x)  // prints "S"

// Will compile after implementation of SE-0068

class A {
required init() {
}

func foo(_ x: Self) -> Self {
print(Self.self)
return Self.init()
}
}

class B : A { }

let y = B()
_ = y.foo(y)  // prints "B"

I find that consistent enough. The annoyance is that we don’t and won’t
have the ability to implement protocol requirements with Self in classes
without Self. This is an error:

protocol P {
func foo() -> Self
}

class A {
func foo() -> A { ... }
}

class B : A {
override func foo() -> B { ... }
}

The fact that we can’t get rid of Self in implementation is an abstraction
leak.

As a side note, seeing Self.self, I really look forward to refactoring Self,
self, Type, Protocol and MemoryLayout.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Add the DefaultConstructible protocol to the standard library

2016-12-28 Thread Anton Zhilin via swift-evolution
What about “Rust way”?

protocol Default {
static var `default`: Self { get }
}

protocol Setupable {
mutable func setup(with params: Params)
}

func setupArray(type: T.Type, params: Params) -> [T]
where T: Default & Setupable
{
return (1...42).map { i in
var next = T.default
next.setup(with: params)
return next
}
}

default is literally a “default” value. For primitives like Int, Char, Bool,
Float etc. it is all zeros. For structs with Default fields, it’s all
defaults—unless some special semantics is given to them. For complex types,
it’s an “empty” value, the most sane value before any setup or
specification.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Move placement of 'throws' statement

2016-12-28 Thread Anton Zhilin via swift-evolution
TLDR: I support moving throws, and also think that ‘typed throws’ should
fit for Phase 2, at least.

let x : (_ a : Int) -> (_ b: Float) throws -> Double throws

Count me in those who cried in anger :)
--

I see why current syntax is very logical for currying:

let x: (Int) throws -> (Float) throws -> Double   // clean

let x: (Int) -> (Float) -> Double throws throws   // looks ambiguous

Although, the ambiguity can be resolved using parentheses:

let x: (Int) -> ((Float) -> Double throws) throws

let x: (Int) -> ((Float) -> Double throws Error2) throws Error1   //
with 'typed throws'

Compare it to how we incorporate optionals (which are just another form of
error handling) in curried functions now:

let x: (Int) -> ((Float) -> Double?)?

Overall, current Swift syntax is uniquely nice to error handling in curried
functions. Is it worth keeping this advantage? Probably not, if the new
form does not contain too much noise and is even more logical. Everything
slides into place, if throws is a binary operator on types with precedence
higher than ->. Although A throws B is not a type on itself, I can clearly
see it becoming one in the future. Then try will handle pattern matching of
such types.

Another point for the suggested syntax: as we now know, Swift users prefer
to see results after -> in function declarations. Is it stretching too far
to conclude that error type is a possible result, and should also come
after ->?
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Replace named returns with `out` parameters?

2016-12-28 Thread Anton Zhilin via swift-evolution
Some people on the list wondered, why we have moved from tuples in function
parameters, but multiple returns are still implemented using tuples? The
following code still compiles:

func position() -> (x: Int, y: Int) {
return (x: 0, y: 0)
}
let (y, x) = position()

(Maybe it’s a bad example, because naturally we’d use Point struct. Let’s
pretend those two parameters don’t make sense as a struct.)

What I want to discuss is if we should introduce out parameters *and* make
them the default for multiple returns for Swift 4. The syntax would look
like:

func position(x: out Int, y: out Int) {
x = 0
y = 0
}
var y
position(x: let x, y: y)

out arguments can be any patterns allowed on the left side of assignment,
including wildcard pattern and tuple destructuring pattern.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Move placement of 'throws' statement

2016-12-27 Thread Anton Zhilin via swift-evolution
This proposal should be reviewed as a part of “typed throws” proposal, with
the original PR  prepared
by David Owens.

Typed throws won’t change anything about how many types can be thrown. Only
one type/protocol will be specified in the function type. You will still be
able to specify throws Error by default, but in the cases, where API
authors put some effort in their error handling, these APIs will be
self-documented and undoubtably easier to work with. In many cases, one can
at least specify some existential error type, which will be
domain-specific, and still better than what we have now.

I feel like Swift, together with Rust, can change current overall mess in
error handling across many programming languages by providing not only
syntax, but also semantics and guidelines. Swift errors, unlike exceptions,
require dealing with them immediately. If one cannot deal with the error,
but error details can be useful on hier levels of abstraction (for actually
solving the problem, not logging), he still should put some work into
wrapping the error, leaving only important details and preparing them for
most conventient access.

On syntax, I feel like this is the obvious one:

func convert(_: String) -> Int throws IntegerConversionError

Basically, we say that the function can either return an Int, or throw an
IntegerConversionError. (Side note: yes, not NumericConversionError, if we
want the API to both provide most detailed information when we need it, and
express the range of possible errors for a particular function through the
type system. However, one can also create hierarchies of error protocols to
aid in abstraction—both abstraction and preciseness are important.)

But can we make a step even further? One can say that the function returns
“either Int or an error”. Rust users blame Swift for creating syntax sugar
for everything—maybe we can live without it this time? Look at it this way:
we already have a deep support for Optional in the language. It’s so
seamless, many people don’t even *realize* they work with Optional. Can
we make working with a standard enum Result this simple?

We can even leave current syntax in place, just T throws E will be a sugar
for Result. Methods of error handling described in this manifesto
 will be
represented, respectively, by Optional, Result, and fatalError, with all of
them defined in the standard library—isn’t that reasonable?
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Swift Closure still inconsistent -- tuple names need to be in curly brackets, single parameter needs to be in parentheses

2016-12-19 Thread Anton Zhilin via swift-evolution
2016-12-20 0:59 GMT+03:00 Derrick Ho :

The core team designed swift blocks to range from concise to verbose. Which
> one you use depends on your needs.
>
> If you want to write parenthesis then by all means write parenthesis; no
> one is stopping you.
>
> I would rather keep the block syntax as it is so that everyone can choose
> the style that matches their needs.
>
> On Mon, Dec 19, 2016 at 1:52 PM Xiaodi Wu via swift-evolution <
> swift-evolution@swift.org> wrote:
>
>> This issue about `numbers in` was raised during review of SE-0066; if I
>> recall, the core team considered and rejected disallowing that syntax in
>> closures. Since we're minimizing source-breaking changes, the issue is
>> settled in my view, having been proposed, commented upon, reviewed, and
>> rejected.
>
> Ok, I understand, you probably consider the syntax in question { param ->
Int in ... } closer to the short form { param in ... } than to the full
form { (param: Int) -> Int in ... }

So when applying analogy, it makes more sense to allow the omission as in
the short form than to disallow as in the full form. I have to agree. So,
-1 to all points of the OP.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Swift Closure still inconsistent -- tuple names need to be in curly brackets, single parameter needs to be in parentheses

2016-12-19 Thread Anton Zhilin via swift-evolution
2016-12-17 2:55 GMT+03:00 Vip Malixi via swift-evolution <
swift-evolution@swift.org>:

var oneParameterAndMultipleReturn: ([Int]) -> (even:[Int], odd:[Int]) = {
> numbers -> ([Int], [Int]) in
> var evenNumberArray = [Int]()
> var oddNumberArray = [Int]()
>
> for number in numbers {
> number % 2 == 0 ? evenNumberArray.append(number) :
> oddNumberArray.append(number)
> }
>
> return (evenNumberArray, oddNumberArray)
> }
>
The above code is valid, because:

   1. Multi-return is just a type of tuple with labeled components.
   2. Labeled tuples and normal tuples are implicitly convertible.

The only way we could make such code invalid is by removing labeled tuples
altogether. -1 on that.
This problem mostly refers to code style, and the above variant can be more
self-documenting in some cases.

Also, again for consistency and clarity, parameters in Closures should
> always be surrounded by parentheses, even single parameters:
>
> var oneParameterAndMultipleReturn: ([Int]) -> ([Int], [Int]) = { (numbers)
> -> (even:[Int], odd:[Int]) in
> var evenNumberArray = [Int]()
> var oddNumberArray = [Int]()
>
> for number in numbers {
> number % 2 == 0 ? evenNumberArray.append(number) :
> oddNumberArray.append(number)
> }
>
> return (evenNumberArray, oddNumberArray)
> }
>
This should be considered a bug. numbers in or (numbers) in or (numbers) ->
(...) in, but not numbers -> (...) in, because the latter forms should be
correct types.
Whether or not just numbers in should be allowed, is another talk.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Pattern matching with Arrays

2016-12-19 Thread Anton Zhilin via swift-evolution
2016-12-19 3:09 GMT+03:00 Lucas Neiva via swift-evolution <
swift-evolution@swift.org>:

> case let [first, next...]:
> > case let [first, last]:
>
> The binding should be more like "[let first, let last]" though, to be more
> like the tuple matching. For the above also: "case [let head, let tail...]".
>
Actually, with tuples, case let (first, last) is equivalent to case (let
first, let last), so the “compact” form should be ok with Array pattern
matching.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Add ability to validate collection indices

2016-12-16 Thread Anton Zhilin via swift-evolution
It will be impossible without huge additional overhead.
I assume that "invalidated" means "no more points to that element".

Consider that an element is inserted in the middle of an Array.
Assuming enough capacity, all iterators after that one will be invalidated.
But all new iterators pointing to the same spots will be valid.
How do you differentiate between the "old" ones and the "new" ones?

I see only one general approach to this:
1. Make iterator type a class
2. Add to the collection, an array of all iterators, which have been
created (and are being used)
3. Add a "valid" flag to iterator
4. On most operations on the collection, it will walk through its
iterators, marking some as "invalid".

It's a safe way to eliminate some "out of bounds" errors, but it's just
utterly rediculous.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Discussion] Generic protocols

2016-12-11 Thread Anton Zhilin via swift-evolution
2016-12-10 14:57 GMT+03:00 Adrian Zubarev :

I’m fine with adding features step by step. ;)
>
> There is no need for an explicit type alias in your
>
> extension MyStruct : Constructible { … }
>
> Because Value is already constrained by String.
>
That was my proposed syntax for inline conversion of associated-types
protocols to generics. In this case, implicit or explicit, this typealias
would appear in MyStruct.

In my typealias examples I mixed *1.* and *4.* together.
>
> protocol GenericFoo : Foo where Value == T { /* nothing here */ }
>
> typealias GenericFoo = Foo where Value == T
>
> I see that the latter cannot produce an actual new protocol, because it’s
> more like a macro and cannot be used multiple times for conformances.
>
> struct D : GenericFoo, GenericFoo {}
>
> // vs.
> struct D : Foo where Value == Int, /* cannot add the second macro for String 
> */ {}
>
> And that is probably why we need real parametrized protocols.
>
That was not an unsolvable problem, but I guess, parametrized protocols is
the first feature to consider.

Questions about *1.*:
>
>- Does it affect ABI or is it needed to simplify the stdlib somehow?
>- Is it something for the current phase?
>
> I found that the only protocol family that looks like it could be replaced
by a generic protocol, is ExpressibleBy* protocols.
But on a closer look, each of them has its own nuances, which prevents us
from using a single LiteralConvertible instead.

So I guess, no existing ABI would need changes, and stdlib is not affected.
So probably it’s not for current phase?
I really wish I’m wrong here.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Discussion] Generic protocols

2016-12-10 Thread Anton Zhilin via swift-evolution
I have to agree with Tino Heth, our aim is to add something basic at first.
Although we’d better make sure that we will be able to add other wanted
features in the future.

How about this plan?

   1. Generic protocols without associated types
   2. Basic conflict resolution using “dot” syntax
   3. Generic protocols with associated types (depends on (2))
   4. Specialization of non-generic protocols with associated types (+work
   on existential notation)

Some inline reply follows.

While trying to find the talk about overlapping protocol members from
> different protocols I spotted your proposal:
> https://github.com/Anton3/swift-evolution/blob/generic-proto
> cols/proposals/-generic-protocols.md
>
This is quite an old listing. Thanks for reminding!

Here is the evolution-thread: https://lists.swift.org/piperm
> ail/swift-evolution/Week-of-Mon–20160919/027122.html
> 
>
> The suggestion there was to prefix everything with the corresponding
> protocol when there is a collision.
>
> struct Test : Foo, Foo {
> init(_ value: Foo.Value) { … }// or better: init(_ value: Int)
> init(_ value: Foo.Value) { … } // init(_ value: String)
>
> // assume both had the function `foo()`
> func Foo.foo() { … }
> func Foo.foo() { … }
> }
>
> That’s a working solution. It doesn’t scale very much, if we try to apply
it to protocol inheritance (conformance) hierarchies, but we shouldn’t care
for now.

Is there really a need for true generic protocols? I’m still
fascinated by the idea how a generic and constrained typealias could
create this new ‘pseudo’ generic protocol.
>
> I agree that ideally, existing protocols should be intact. If so, then we
should consider “the original protocol with associated types” and
“explicitly specialized protocol” as two different protocols:

protocol Constructible {
associatedtype Value
func foo()
}
struct MyStruct : Constructible {
typealias Value = Int
func foo() { }
}
extension MyStruct : Constructible {  // or
Constructible, or whatever
typealias Constructible.Value = String
func Constructible.foo() { }
}
MyStruct.Value  // IntMyStruct.Constructible.Value  // String
func bar(t: T)  // can call with MyStructfunc bar>(t: T)  // can NOT call with MyStructfunc bar>(t: T)  // can call with MyStruct

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


Re: [swift-evolution] [Discussion] Generic protocols

2016-12-09 Thread Anton Zhilin via swift-evolution
A fundamental problem is, how do we get rid of associatedtype duplicates?

A pedantic approach is to add trait operations for conformances:

protocol Constructible {
associatedtype Value
init(_ value: Value)
}
struct MyStruct {
conformance Constructible {
rename associatedtype ValueInt = Value
}
conformance Constructible {
rename associatedtype ValueString = Value
}

typealias ValueInt = Int  // or can be inferred
init(_ value: Int)

typealias ValueString = String  // or can be inferred
init(_ value: String)
}

This way, if there is a if there is a conflicting member, which does not
use any of the associated types, like func foo(), then we can give it
different meanings in different conformances.
Although this approach is the most clean one from theoreticall point of
view, choosing different names for associated types would not look very
good in practise.

One possible solution is to *always* automatically match associatedtypes,
without using typealiases.

protocol ConstructibleFromBoth {
associatedtype First
associatedtype Second
init(first: First)
init(second: Second)
}
struct MyStruct : ConstructibleFromBoth {
init(first: Int)
init(second: Double)
}
extension MyStruct {
init(first: String)   // now there are 2 distinct conformances
}
extension MyStruct {
init(second: Float)   // now there are 4 distinct conformances
}

It introduces another potentially exponential algorithm for compiler.
Although, does it? During a conformance test in some generic function,
compiler will need to only find the first match or two.
Anyway, I guess, people would prefer to state explicitly that a type
conforms to multiple versions of a protocol.

Attempt #3. We can resolve the conflict between associated types, if we
delete (if trait sense) confliting associated types from the type. But with
extensions, all associated types can be made conflicting. So there needs to
be some attribute, marking, which of the associated types we don’t want. It
can lie at the place of conformance:

struct MyStruct { }extension MyStruct : @dontCreateTypealiases
(Constructible where Value == Int) { ... }extension MyStruct :
@dontCreateTypealiases (Constructible where Value == String) { ... }//
MyStruct.Value.self  // error, no such type
struct NormalConformanceTest : Constructible { init(_ value: Float)
}NormalConformanceTest.Value.self  //=> Float

Or we can let constrained protocols syntax carry this attribute by default:

extension MyStruct : (Constructible where Value == Int) { ... }//
MyStruct.Value.self  // error, no such type
struct NormalConformanceTest: Constructible { init(_ value: Float)
}NormalConformanceTest.Value.self  //=> Float

The only thing left to solve is generic protocol declaration syntax and
protocol specialization syntax. I’d like to present two ways to do this.
First, taking ideas from Rust:

protocol ContainsCollection {
associatedtype CollectionType : Collection where
CollectionType.Element == Element
func collection() -> CollectionType
}
extension String : ContainsCollection,
ContainsCollection, ContainsCollection {
func collection() -> CharacterView
func collection() -> UnicodeScalarView
func collection() -> ContiguousArray
}

Generic parameters are used to disambiguate between different conformances,
and associated types are just matched. Explicit typealias specifiction is
prohibited, because conflicts.

Second, without modifying current protocol declaration syntax:

protocol ContainsCollection {
associatedtype Element
associatedtype CollectionType : Collection where
CollectionType.Element == Element
func collection() -> CollectionType
}
extension String : ContainsCollection,
ContainsCollection,
ContainsCollection {
func collection() -> CharacterView
func collection() -> UnicodeScalarView
func collection() -> ContiguousArray
}

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


Re: [swift-evolution] [Discussion] Generic protocols

2016-12-06 Thread Anton Zhilin via swift-evolution
What makes me worry is if this syntax is really the best one possible:

typealias ConstructibleFrom = ConstructibleFromValue where ValueType == V

I find it strange that such exact line with typealias and where is
required. I was hoping for an expression that lets us specialize a protocol
and use it in-place, like so:

extension MyType : ConstructibleFromValueextension
MyType : (ConstructibleFromValue where ValueType == V)

Also I thought that this topic does not really belong to generalized
existentials:

var x: ConstructibleFrom

I mean, we specify all the types here, so the compiler should just
specialize the protocol and use it as a normal existential. The only thing
that does not allow us to do that now is syntax.
By comparison, the following typealias does require generalized
existentials, because some associatedtypes, including Iterator, are not
specified:

typealias GenericCollection = Collection where Iterator.Index ==
Int, Element == E

It also shows that future generalized-existentials syntax will likely be
exactly the same as the one we choose now for protocol specialization.
So we still should think twice before proceeding. We can implement this
proposal now, but do we want to?
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Allow explicit type parameter specification in generic function call

2016-12-02 Thread Anton Zhilin via swift-evolution
2016-12-02 3:55 GMT+03:00 Ramiro Feria Purón :

> *Unlike C++'s templates, a Swift's generic function is semantically a
> single function.*
>
> Anton, could you provide further insight on this?
>

Basically, generic functions in Swift are implemented as functions taking
an additional parameter -- witness table, which contains implementation of
all functions in the protocol.
For example, the following:

func f(a: T, b: T)

Turns into something like:

func f(a: Any, b: Any, witnessTableForT: UnsafePointer<_WitnessTable>)

Returning to my cited phrase, Swift specializes generic types (with
duplicated metadata; think C++ class specialization), but implements
generic functions without using specialization. One can say that a generic
type in Swift becomes a collection of distinct types, but a generic
function remains a single function. So we can't view them equally, and
current situation, where we can "explicitly specialize" types, but not
functions, is not an inconsistency.

I used word "semantically", because compiler can apply *specialization
optimization* to a function, which is usually followed by inlining. But
this optimization is guaranteed not to break the above assumptions.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Allow explicit type parameter specification in generic function call

2016-12-01 Thread Anton Zhilin via swift-evolution
I disagree with the suggestion. Unlike C++'s templates, a Swift's generic
function is semantically a single function. One can say that together with
a metatype parameter, we pass in witness table.

What I think we should do is make metatypes easier to use. *Adrian and I
have a PR* that has already been waiting for almost a month:
https://github.com/apple/swift-evolution/pull/553
Plus, removal of .self could simplify such calls.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Some concerns on custom operators

2016-11-28 Thread Anton Zhilin via swift-evolution
2016-11-28 5:09 GMT+03:00 Robert Widmann via swift-evolution <
swift-evolution@swift.org>:

> That is what was happening for me at the time.  Operadics was exporting
> bind (>>-), ap (<*>) and fmap (<^>), and SwiftCheck was pulling in
> Operadics inline in the non-SPM build.  The two modules were literally
> trying to export the same operators with the same precedencegroup
> declarations.  My definition of “perfectly identical” covers this case.
>
> > The definition of "perfect duplicates" is more complex now.  It would be
> easy to ignore duplicates that name the same precedencegroup, but that's
> probably not what's happening here.
>
> In that case there is a nice structural equality that falls out of the
> current way things are defined, more so than before given that we can use
> the relative precedences (and given that most libraries don’t set up
> precedencegroup lattices that are complex as TypeLift does).  Essentially,
> the problem is verifying a bisimulation with alpha-equivalence at all the
> edges.


Would allowing duplicate precedence group declarations solve the problem?
AFAIK, operators are already merged this way.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Symmetrical operators

2016-11-14 Thread Anton Zhilin via swift-evolution
-1
Not worth adding syntactic sugar for a narrow use case. Plus it's an
additive feature.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Some concerns on custom operators

2016-11-09 Thread Anton Zhilin via swift-evolution
2016-11-09 22:20 GMT+03:00 John McCall <rjmcc...@apple.com>:

> > On Nov 9, 2016, at 9:25 AM, Anton Zhilin via swift-evolution <
> swift-evolution@swift.org> wrote:
> >   • Upon implementation of SE-0077 in Swift 3, some libraries
> started to drop operators entirely: link #1, link #2.
> >   • Declarations of the same custom operator with different
> precedence groups create a conflict.
> >   • The conflict can be resolved manually, but the
> resolution has to be made in every file that uses the operator, which
> defeats the reason for using operators in the first place.
> >   • This is a part of a larger problem of conflict
> resolution, for which we don’t currently have a systematic approach.
>
> It makes sense to me to provide a more module-wide conflict resolution
> mechanism.  Maybe we can have some sort of "internal export" mechanism
> where a file can introduce imports into other files within a project.
>

It would also be generally useful for modules that are made use of
throughout the project, like logging or those generic operators and
collections libraries. I can create a proposal for that.

>   • Many libraries dealing with custom operators choose to
> import Runes, which is basically a stockpile of operator declarations. But
> it conflicts with Result, Swiftx and Operadics.
>
> Won't this just shake itself out pretty soon, assuming these projects have
> any interest in interoperating?


Maybe. Anyway, "internal import" can make such conflicts not that much of a
problem.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Some concerns on custom operators

2016-11-09 Thread Anton Zhilin via swift-evolution
2016-11-09 21:56 GMT+03:00 Joe Groff :
>
> Do you know if bugs have been filed about these issues? IIRC, SE-0077
> specified that precedence groups should act like normal named declarations
> and be scopable. The fact that they aren't sounds like a bug to be fixed.
>

I don't know of any. At one stage during review a core team insisted on
that, because it is simpler to implement, plus conflicts in custom
operators sphere are unavoidable anyway. But I agree that it can be
considered a bug.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Some concerns on custom operators

2016-11-09 Thread Anton Zhilin via swift-evolution
   1.

   Upon implementation of SE-0077 in Swift 3, some libraries started to
   drop operators entirely: link #1
   , link #2
   .
   - Declarations of the same custom operator with different precedence
  groups create a conflict.
  - The conflict can be resolved manually, but the resolution has to be
  made in *every* file that uses the operator, which defeats the reason
  for using operators in the first place.
  - This is a part of a larger problem of conflict resolution, for
  which we don’t currently have a systematic approach.
  - Many libraries dealing with custom operators choose to import Runes
  , which is basically a stockpile
  of operator declarations. But it conflicts with Result, Swiftx and
  Operadics.
   2.

   Even if operator conflicts are resolved, precedencegroups’ names are not
   module-scoped, and don’t support conflict resolution.
   - Many libraries decide to just go ahead and prefix precedencegroups
  with module name.
  - Some developer on Github specifically complained about having to do
  this, but I’ve lost the link.
   3.

   Some precedencegroup names don’t seem perfect to me. This concern may
   not be strong enough to make a source-breaking change, though.
   - LogicalDisjunctionPrecedence -> DisjunctionPrecedence
  - LogicalConjunctionPrecedence -> ConjunctionPrecedence
  - BitwiseShiftPrecedence should be renamed to ExponentiationPrecedence,
  if we decide not to branch bitwise operators off arithmetic.
   4.

   For the mentioned branching, I’m going to post a separate [Pitch] soon.

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


Re: [swift-evolution] [Pitch] Nil struct

2016-11-08 Thread Anton Zhilin via swift-evolution
2016-11-09 0:12 GMT+03:00 Adrian Zubarev :

Could you elaborate an implementation for one of these functions:
>
func == (left: T?, right: Nil) {
switch left {
case .some(_): return false
case .none: return true
}
}

The implementation is basically the same as of now, except that instead of
Nil, there is _OptionalNilComparisonType.

Main use case of Nil would essentially be partial specialization of
functions.
See example with optional comparison: there exists a generic version that
takes a proper ExpressibleByNilLiteral (in this case Optional), but we
can apply simpler logic in case we see nil.

Frankly speaking, I’m not sure myself this feature would find any use
except for the mentioned optional comparison operators.
So I will probably stop pushing this forward.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Nil struct

2016-11-08 Thread Anton Zhilin via swift-evolution
2016-11-09 0:11 GMT+03:00 arkadi daniyelian :

I could not clearly see the exact, concrete problem with the current
> implementation. IMAO such fundamental change requires a *very* serious
> reason and some thought on performance side of thing.
>
Performance will not be hurt, because as Robert noted, Nil will be
isomorphic to ().
Concrete problem, as stated in the proposal, is “hacks” that standard
library has to contain, because nil does not have its LiteralType.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Nil struct

2016-11-08 Thread Anton Zhilin via swift-evolution
2016-11-08 23:44 GMT+03:00 Adrian Zubarev :

At first glance this doesn’t make any sense to me:
>
> public protocol ExpressibleByNilLiteral {
>   associatedtype NilLiteralType = Nil
>   init(nilLiteral: NilLiteralType)
> }
>
> What’s the need for associatedtype there?
>
> Shouldn’t it be just like this:
>
> public protocol ExpressibleByNilLiteral {
>
>   init(nilLiteral: Nil)
> }
>
> Probably. I just looked at ExpressibleByBooleanLiteral, and it contained
BooleanLiteralType, which should always be Bool by convention.
If someone knows, why this associatedtype is needed in
ExpressibleByBooleanLiteral, please explain.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Nil struct

2016-11-08 Thread Anton Zhilin via swift-evolution
2016-11-08 23:43 GMT+03:00 Jose Cheyo Jimenez :

Thank for thinking of this. I am not sure on the advantage of having nil as
> a concrete type.
>
> Have you seen this talk?
>
> https://realm.io/news/swift-summit-al-skipp-monads/
>
> "The concept of “nil” does not exist in Swift (despite the existence of
> the keyword nil!)"
>
> Does that talk change your mind about this pitch?
>
Not much. We can talk about Swift literals being untyped as much as we
want, but still all of them, except for nil, have an internal storage type,
which is also picked by default.
For example, integer literals are Builtin.Int2048, if I’m not mistaken. But
we just can’t store nil without creating an instance of a potentially
complex type.

And this proposal is not about adding nil to all types. You can do this now
with Any, in any case:

let optionalInt1: Any = 42let optionalInt2: Any = ()   // ewww

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


[swift-evolution] [Pitch] Nil struct

2016-11-08 Thread Anton Zhilin via swift-evolution
Gist link 
Introduction

Change nil literal type from () to Nil.
Before:

public protocol ExpressibleByNilLiteral {
  init(nilLiteral: ())
}

After:

public struct Nil {
  init()
}
public protocol ExpressibleByNilLiteral {
  associatedtype NilLiteralType = Nil
  init(nilLiteral: NilLiteralType)
}

Motivation

Currently, nil differs from other literals: it doesn’t have its own type.
But in some cases we want to deal directly with it, without creating any
instances.

The most important use case is comparison of an Optional to nil.
Currently, this operation is implemented using a hidden struct
_OptionalNilComparisonType,
which is needed precisely because because nil does not have its own type.
Removal of such underscored types is one of the goals stated in Generics
manifesto.

Additionally, declaration of ExpressibleByNilLiteral differs from all other
Expressibles,
because it doesn’t have a Literal type. It is generally beneficial to
eliminate special cases.
Proposed solution

Introduce a struct Nil, which becomes the default type for nil literals:

public struct Nil : ExpressibleByNilLiteral {
  init()
  init(nilLiteral: NilLiteralType)
}
let a = nilprint(type(of: a))   //=> Nil

Rewrite ExpressibleByNilLiteral:

public protocol ExpressibleByNilLiteral {
  associatedtype NilLiteralType = Nil
  init(nilLiteral: NilLiteralType)
}

Make use of Nil in the standard library:

public func == (left: T?, right: Nil)public func == (left: Nil,
right: T?)public func != (left: T?, right: Nil)public func !=
(left: Nil, right: T?)public func ~= (left: Nil, right: T?)

Source compatibility

Nil identifier is taken, therefore applications that already use it will
stop compiling.
Automatic migration is somewhat possible by renaming of the old entity;
manual migration is recommended.

Applications that use declare ExpressibleByNilLiteral conformances will
stop compiling.
Automatic migration is possible.
Effect on ABI stability

Applications that use Nil identifier will have to make ABI-breaking changes.

Otherwise, the change can mostly be applied in an ABI-compatible manner.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Postfix operators that start with ? or !

2016-11-01 Thread Anton Zhilin via swift-evolution
Hello Tony,
Feel free to file a bug report. If there are no spaces between operator
characters, then they should be parsed as a single operator.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Reimagining guard case/if case

2016-10-29 Thread Anton Zhilin via swift-evolution
I'd like to write a proposal for "matches" and wonder if it is in Swift 4
Phase 1 scope? It's purely syntactic, and won't affect ABI.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Replace the ternary operator with an in-language function

2016-10-26 Thread Anton Zhilin via swift-evolution
infix operator ♠️ : LogicalDisjunctionPrecedenceinfix operator ♥ :
LogicalDisjunctionPrecedence
func ♠️(lhs: Bool, rhs: @autoclosure () throws -> T) rethrows -> T? {
if lhs { return rhs() } else { return nil }
}func ♥(lhs: T?, rhs: @autoclosure () throws -> T) rethrows -> T {
return lhs ?? rhs
}
// Equivalent statements:
condition() ? first() : second()
condition() ♠️ first() ♥ second()

By removal of ?:, we could simplify our system of operators and prevent
some ternary-related bugs/unexpected stuff. We could modify reserved
operators to allow ? instead of ♠️ and : instead of ♥.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Refining Identifier and Operator Symbology

2016-10-25 Thread Anton Zhilin via swift-evolution
Why can't we just remove distinction between operator and identifier
symbols? I'd be fine with the following:

```swift
infix operator map
infix func map(lhs: [Int], rhs: (Int) -> Int) { ... }
[1,2,3] map {$0*2}
```

No explicit imports required, plus we can create nice DSLs. Of course, it's
an additive change, but it's worth considering right now, because it can
remove some headache caused by current distinction.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Reimagining guard case/if case

2016-10-25 Thread Anton Zhilin via swift-evolution
Haravikk, I fully agree with you; before I read your post I thought I’d
write exactly that.
if  matches 

1.
Another “ideological” reason:
= is just an operator, so lhs = rhs should be an expression, but meaning of
= is overloaded in this context. On the other hand, when you see a keyword,
you can’t mistake if lhs matches rhs for an expression. Analogy with for-in
plays here.

2.
Does this change simplify the syntax enough that we can remove optional
binding?
Is if x matches y? short/simple enough by comparison to if let x = y?
I think yes, because matches is so much clearer.

3.
We can do the same change for for case pattern in, plus eliminate where
clause? How about this:
for x in y, x matches z?, condition, w matches x

let results: [Either]
for item in results, item matches .left(let num), num >= 0 {
print(num)
}

Looks like it’s closer to logical sequence of actions, than what we
currently have. Now we have “select .left elements, while iterating through
results, and only select those which are >= 0“.

P.S. We can leave where, or even if in this form of for-in.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2016-10-18 Thread Anton Zhilin via swift-evolution
I'd prefer to replace $ with # in closure parameters, plus make $ equal in
rights to other currency symbols.
In C and JS, dollar sign is actually equal in rights to other currency symbols.
Swift is closer to them than to Perl, Shell, PHP, so it makes sense to
follow them here.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [pitch] "import" declaration, support for comma-separated modules

2016-10-16 Thread Anton Zhilin via swift-evolution
Purely additive feature, not for Swift 4 Phase 1.
And a -1 from me for reasons already mentioned.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] stored properties in extensions (was: associated objects)

2016-10-15 Thread Anton Zhilin via swift-evolution
Currently, we can expect that fields of a type are all collected in the
same place. This expectation applies more for "static" and less for
"dynamic" types.
So I agree with the idea for @objc classes, strongly disagree for structs,
and disagree for regular classes.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Conditional casting and conditional binding: Wierd edge case or flawed design

2016-10-09 Thread Anton Zhilin via swift-evolution
A quick fix:

guard let value = dict["Key"].map({ $0 as NSString }) {
use(value)
}

Current behavior is quite logical: main purpose of as? is to perform casts,
which are not guaranteed to succeed. But I’d say that as? should also
support what you want.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] private & fileprivate

2016-10-08 Thread Anton Zhilin via swift-evolution
As far as I can see, almost all people, who talk here, agree that private /
fileprivate distinction brought more harm than good. Despite corresponding
proposal being accepted.
I think, it means that current mailing-list system is failing. Let's accept
it, gmane looks and feels ugly by comparison to forums. And using email
limits the number of people involved by an order of magnitude.
What we need is popularization of SE, reaching as many developers as we
can, using simple voting, likes, and so on.

2016-10-08 12:31 GMT+03:00 Haravikk via swift-evolution <
swift-evolution@swift.org>:

>
> > On 7 Oct 2016, at 22:44, Tony Allevato via swift-evolution <
> swift-evolution@swift.org> wrote:
> > personally I thought `private` was fine the way it was when it meant
> `fileprivate` and I had no real need for `private` as it exists in Swift 3.
>
> I have to agree with this; I wasn't especially comfortable with the change
> (or the eventual choice of keyword style) and in practice I just don't find
> it useful. I haven't used the new "private" even once since it was added,
> except by accident, the only form of private I use is fileprivate.
>
> I've happily embraced the conform through extension style in Swift, and
> really when it comes down to it the new private access level just isn't
> compatible with that style of development. It's only really useful for
> hiding details of something you add in one specific section, which I almost
> never do (and when I do I just mark it fileprivate in case I can re-use it).
>
> Maybe some people do find it useful, but I'd prefer fileprivate to be the
> default behaviour of private; the current (scoped?) private access level
> seems far more limited, thus more deserving of a less convenient keyword,
> or some kind of modifier on private. But personally I'd be fine with
> removing it, as I don't think it really adds anything that fileprivate
> doesn't already cover.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [Question] Types of functions

2016-10-05 Thread Anton Zhilin via swift-evolution
// Swift 2.2print([Int].append.dynamicType)  //=> inout Array ->
Int -> ()print(print.dynamicType)  //=> (Array>, String,
String) -> ()
// Swift 3print(type(of: [Int].append))  //=> (inout Array) ->
(Int) -> ()print(type(of: print))  //=> ((Array, String, String))
-> ()

Question #1: Methods are still curried. If I’m not mistaken, there was an
accepted proposal that uncurries methods. Is it going to be implemented for
Swift 4 Stage 1?

Question #2: Why nested tuple in type of print? Is it just a formatter bug,
or… do functions still take tuples under the hood? If so, then perhaps,
implementation needs to be modified to actually use new model, and not just
make it look like it does.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Refactor Metatypes

2016-09-30 Thread Anton Zhilin via swift-evolution
2016-09-30 22:48 GMT+03:00 Xiaodi Wu via swift-evolution <
swift-evolution@swift.org>:

Sorry, my question at least has nothing to do with bikeshedding. I'm
> confused about why the proposal feels it's necessary to have both Type and
> Subtype. I don't understand Brent's two reasons and was hoping for some
> elaboration. I've tried to clarify my question in a gist:
>
> https://gist.github.com/xwu/0cc2c8d358f1fdf066ba739bcd151167
>
Regardless of syntax, there are Metatype and ExistentialMetatype
“under the hood”. I’ll take the liberty to use these names for this post.

Purpose and difference between the two kinds of metatypes is easy to
understand. If it helps, size of Metatype is typically 0 while size of
ExistentialMetatype is typically 8.

NOTE: Metatype can’t be a subtype of ExistentialMetatype for
protocols P, because protocols do not implement their own static
requirements.

Apparently, creators of Swift also thought that two kinds of metatypes are
too difficult for an average developer. So an attempt was made to unify
both under a single name, T.Type. For “final” types like structs, T.Type
maps onto Metatype. For classes and protocols, T.Type maps onto
ExistentialMetatype.

This abstraction turned out to be leaky. I’ll give 3 leaks.

   1. Because of Note, we could not have ID of a protocol itself inside of
   any kind of metatype. This feature was needed in real code. The solution
   was to add T.Protocol syntax that could only be used for protocols to
   create a Metatype. But this solution created a plethora of other
   inconsistencies and abstraction leaks (which were explored by Adrian).
   Arguably the most important is (2).
   2. In generic functions accepting T.Type, passing T.self creates an
   instance of T.Protocol, which is still described in code as T.Type.
   *boom!*
   3. Accepting static metatypes in functions is often what people want.
   Consider the following basic example:

func create(type: T.Type)

Most probably, create does not read contents of type to deal with
appropriate subtype. It does not support existentiality, type is here for
function specialization. But in case T is subtypable, we still pass around
those 8 bytes that are not used by the create, confusing both compiler and
some developers. In 90% cases, when we see such a function, it throws off
value of metatype instance.
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Refactor Metatypes

2016-09-29 Thread Anton Zhilin via swift-evolution
2016-09-29 3:31 GMT+03:00 Colin Barrett via swift-evolution <
swift-evolution@swift.org>:


>-
>
>Type is the concrete type of T.self. A Type only ever has one
>instance, T.self; even if T has a subtype U, Type is not a subtype
>of Type.
>-
>
>Subtype is the supertype of all Types whose instances are subtypes
>of T, including T itself:
>-
>
>If T is a struct or enum, then Type is the only subtype of
>Subtype.
>-
>
>If T is a class, then Type and the Types of all subclasses of T are
>subtypes of Subtype.
>-
>
>If T is a protocol, then the Types of all concrete types conforming to
>T are subtypes of Subtype. Type is not itself a subtype of
>Subtype, or of any Subtype other than Subtype.
>
> I’m having trouble reconciling this with rule #2 above, which states that
> “Subtype is the supertype of all Types whose instances are subtypes of T,
> including T itself.” Which one is wrong, or am I confused?
>
#2 applies to types, and #5 applies to protocols. If T is a type, then
Type is always a subtype of Subtype. If T is a protocol, then Type
is never a subtype of Subtype.

One thing I haven’t understood the motivation for exactly is what someone
> would be able to do with a Proto.self. Dynamic conformance checking? For a
> concrete T, having its .self seems useful for doing dynamic casts and such,
> but I don’t understand why for a Proto you need to have both. You did a
> good job of explaining why T.Protocol and T.Type are different, but not why
> both of them need to exist. So you could definitely do more to spell out
> the use-cases here.
>
I honestly can’t imagine a use case for .Protocol currently. Maybe
enumerating protocols that exist in the program, just for the sake of it.


>-
>
>Metatypes of functions are a little bit more special (the subtyping
>relation on functions flips around for parameter types
>
> 
>):
>-
>   - Type<(Any) -> Void> is a subtype of Subtype<(Int) -> Void> etc.
>   - Type<(Void) -> Int> is a subtype of Subtype<(Void) -> Any>
>
>
> Does this potentially expose contravariant type parameters, and is that an
> issue? (I’m trying to imagine a scenario where you could have an A on the
> left hand side of an arrow and have that leak out to other clients, but I
> haven’t had a chance to write much Swift 3 yet, unfortunately.)
>
Could you give a code example, where that would be an issue?
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal draft] Conditional conformances

2016-09-28 Thread Anton Zhilin via swift-evolution
I find the limitation of non-intersection of conditional conformance
reqirements quite limiting. Can it be lifted in case there are no
overloaded functions between extensions?

protocol A { func foo() }
protocol B { func bar() }

extension Array: A where Element: A {
func foo() { return self.first!.foo() }
}
extension Array: B where Element: B {
func bar() { return self.first!.bar() }
}

let arr: Array
arr.foo()

What is ambiguous here? When we see arr.foo(), we know it's from Array: A
extension, regardless of T, and we just have to check the requirement of
that extension.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Source-breaking proposals?

2016-09-25 Thread Anton Zhilin via swift-evolution
Do I miss something, or proposals with source-breaking changes still can't
be submitted?
When will corresponsing guidelines be out? Are there any plans on that
matter?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] pattern matching on variable-sized data type

2016-09-06 Thread Anton Zhilin via swift-evolution
You can process lists using pattern matching today:

enum List {
case Nil
indirect case Cons(T, List)
}
let list: List = .Cons(2, .Cons(3, .Nil))
switch list {
case .Nil: ...
case .Cons(let x, .Nil): ...
case .Cons(let x, .Cons(let y, .Nil)): ...
default: handleLongList(list)
}

The thing is, such lists are not idiomatic in Swift. Pattern matching on
Array also kind-of works:

let array: Array = ...
switch array.first {
case .some(let first):
processHead(first)
processTail(array.dropFirst())
case .none:
handleNil()
}

Again, it’s not the most idiomatic way to do this in Swift. Also, there is
no guaranteed tail-call optimization.

2016-09-06 17:48 GMT+03:00 Jean-Denis Muys via swift-evolution <
swift-evolution@swift.org>:

Hello,
>
> I would like to suggest an additive evolution to Swift that might be in
> scope of phase 1 of Swift 4 (because it might have an impact on the ABI).
>
> The idea is to extend the pattern matching abilities of Swift to enable a
> recursive programming style that’s very common in languages such as Lisp,
> ML, or Prolog on a collection that is processed as a list. By analogy to
> ML, Swift could do that on tuples, or on arrays, or on any similar, perhaps
> new, data type. This would allow the following for example:
>
​
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] #pragma

2016-09-05 Thread Anton Zhilin via swift-evolution
AFAIK, if one would extend Swift beyond its "official" specification,
it could be done using #-directives and @-attributes, like Swift
playgrounds use #imageLiteral(...) and friends. It's somewhat equivalent to
pragmas of C++. On the other hand, things that are not understood by target
compiler, but are features of an IDE, are done using comments. Fair enough?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch]: Require parenthesis for ternary operator '?:' or change its priority

2016-09-03 Thread Anton Zhilin via swift-evolution
With the replacement, I would prefer just "then-else", which would still
clearly carry the meaning of low priority. But yes, this option was
explicitly rejected. Unfortunately.

I also agree that changing the priority is not a solution. But how about
removing priority?

The following expression:
`s << (x == 10) ? "10" : "not 10"`
Is currently parsed as
`(s << (x == 10)) ? "10" : "not 10"`

With such a change, the compiler would make you add outer parentheses and
find a bug, by the way:
`s << ((x == 10) ? "10" : "not 10")`

Should this apply to assignment operators?
`s += (x == 10) ? "10" : "not 10"  // error?`

I think such caveats of `?:` are worth creating a proposal, at least.

2016-09-03 14:21 GMT+03:00 Thorsten Seitz via swift-evolution <
swift-evolution@swift.org>:

> The problem you describe is not the priority of the ternary operator but
> that developers just assume a priority without checking (or learning)
> whether their assumption is correct. Changing the priority won't solve that
> problem, it would only shift the problem over to those developers assuming
> the other priority. Worse, it would create this problem for those
> developers knowing the correct priority, because they now have to relearn
> the new priority with the added difficulty of the priority being different
> from C.
>
> I'm not sure whether the problem really is one (other operators have
> priorities too, which have to be learned), but assuming for the moment that
> it is, a solution would be to replace the ternary operator with an
> if-expression: *if* condition *then* expr1 *else* expr2
> This would enclose the condition between two keywords and thereby be free
> of misunderstandings.
> Replacing the ternary operator is on the commonly asked changes list,
> though, and therefore requires new arguments/insights why a replacement
> would make sense. I think the possibly confusing priority has been
> discussed already in the past and therefore wouldn't count as new insight,
> though I'm not quite sure.
>
> -Thorsten
>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Type-annotated throws

2016-08-29 Thread Anton Zhilin via swift-evolution
+1 for removing Error protocol. Then it's a breaking change, and this
edition of the proposal can be reviewed for Stage 1.
Swift error model tries to be different (better) than of other languages.
We encourage not to rethrow, but to think of errors as of meaningful
results and process them accordingly, at all levels of abstraction.
Right now, the formal proposal can't be submitted, but discussion is fine.

2016-08-29 12:18 GMT+03:00 Tino Heth via swift-evolution <
swift-evolution@swift.org>:

> I'm quite skeptical here (Java has already been mentioned…), but if it's
> done, I'd vote for removing ErrorType:
> This empty protocol always felt a little bit odd to me, and when each
> function has information about what errors to expect, imho there is
> absolutely no benefit associated with conformance.
> Even now, it's not that much — or does anyone actually consult a list of
> conforming types for error handling?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Type-annotated throws

2016-08-26 Thread Anton Zhilin via swift-evolution
Forwarding to more people:
This idea has already been discussed, and Chris Lattner specifically
mentioned that this proposal will be suitable for Swift 4 Phase 2. But
right now we shouldn't create a proposal for this.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Type-annotated throws

2016-08-26 Thread Anton Zhilin via swift-evolution
Felix, this idea has already been discussed, and Chris Lattner specifically
mentioned that it is planned for Swift 4 Phase 2. But right now we
shouldn't create a proposal for this.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Require Any for existentials

2016-08-25 Thread Anton Zhilin via swift-evolution
Syntax for `T == P || T: P` is off-topic for current proposal, which is
just about replacing `P` with `Any`.

Currently, equivalent of `Any` has no subtypes (besides itself). This is
likely not going to be changed. So `where U : Any` will not be allowed.

Generalized existentials also don't solve this problem. Existential
`Sequence` would look like this:

`Any`

Here, we can't accept `Iterator.Element == Any` for the same reason that
we can't accept `Any : P` in any other place: static member requirements
are not implemented.

To solve this problem, we should invent another generic requirement, say
`:==`, that prohibits calling static members on generic parameter. This
should be a separate proposal. `Any` can't help here, because the
problem with calling static members only happens with static polymorphism.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


  1   2   3   >