Re: [swift-evolution] Optional Argument Chaining

2017-12-17 Thread Elviro Rocca via swift-evolution
While it's definitely worth knowing, it's not a really usable substitute for 
higher-kinded types in production code, and still requires a lot of code 
generation, which is eased in Kotlin thanks to its annotation/metaprogramming 
features.

Event the Kategory people recognized that the emulation approach is a temporary 
solution, waiting for the approval of a proposal for the addition of HKTs to 
Kotlin itself.

Unfortunately, if we don't get HKTs in Swift we're simply going to miss on a 
barrage of extremely useful abstractions, upon that many contemporary languages 
have started to rely, because they are simply the best known solutions to many 
problems in many contexts.

The huge amount of work that's been done in academia in the last 15 years (and 
it's still going) about applicatives - and also profunctor optics, another 
thing that requires HKTs - is mostly going to elude Swift due to its crucial 
lack of expressivity.

We're on the right track with the approval of the conditional conformance 
proposal, but my fear is that the ABI stability requirement for Swift 5 is 
going to lock the language interfaces in a state where it's going to be 
impossible for these kinds of sophistications to be added to the language at a 
later stage... I hope to be proven wrong here.


Elviro 

> Il giorno 14 dic 2017, alle ore 15:40, Matthew Johnson via swift-evolution 
>  ha scritto:
> 
> 
> Thanks for jumping in and elaborating on a more general approach!  I don’t 
> want to sidetrack the thread, but it actually is possible to encode 
> higher-kindred types and protocols requiring them in Swift today.  It’s a bit 
> clunky and requires some boilerplate but the technique is worth knowing.  
> https://gist.github.com/anandabits/f12a77c49fc002cf68a5f1f62a0ac9c4 
> 
> 
> Some Kotlin folks have created a pretty robust FP library using the same 
> technique: http://kategory.io/ .
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [draft] Introduce Sequence.filteredMap(_:)

2017-10-24 Thread Elviro Rocca via swift-evolution
"Flattening" in the context of functional programming (and that's where map and 
flatMap come from) means something like this:

F> -> F

So for example:

Array> -> Array

or

Optional> -> Optional

but NOT:

Array> -> Array

It's simply the wrong word for the operation.

If "Map" is something like this:

(F + (T -> U)) -> F

then "FlatMap" means "map to the same functor, then flatten", thus:

(F + (A -> F)) -> F>
then 
(F> -> F)

In this case "U == F"

In fact, there's (rightfully) a FlatMap method on Optional in cases in which 
the mapping function produces another Optional (notice that the chained 
unwrapping with "?." is a FlatMap operation).

Calling FlatMap something that is not (in the literature and community at 
large) was not a good idea, in my opinion.

Elviro

> Il giorno 24 ott 2017, alle ore 14:10, Tino <2...@gmx.de> ha scritto:
> 
> 
>> Calling "flatMap" a map + filtering out the nil values was a TERRIBLE idea.
> maybe I’m the one who’s getting this all wrong, but afaik the purpose of 
> flatMap isn’t filtering out nil at all, but just a combination of map & 
> flatten…
> Optional is like Array with a maximal capacity of one (so it can either 
> contain a single object, or it’s empty), and in this interpretation, there’s 
> nothing wrong with the behavior.
> 
> Instead, I think Nobuo Saito is right, and that a renaming to filteredMap is 
> only fighting symptoms, and not the cause (but I’m not that sure if there’s a 
> good way to tackle the cause).
> Besides that, all those alternative names also have potential for confusion:
> Imho it isn’t intuitive what is filtered out — and don’t forget that the 
> result of flatMap can contain nil elements…
> 
> If the biggest problem of flatMap is that people who don’t understand it 
> write code that isn’t optimal (but still does the right thing!), I don’t 
> think there is any change needed. I’m not even sure that that 
> wrapping/unwrapping is actually done, because it should be discoverable by 
> the compiler.
> 
> It would be nice if there was an way to warn in places where flatMap could be 
> replaced with map, though (but imho this special warning shouldn’t be checked 
> by the compiler).
> 
> - Tino

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


Re: [swift-evolution] [draft] Introduce Sequence.filteredMap(_:)

2017-10-24 Thread Elviro Rocca via swift-evolution
Huge +1

Calling "flatMap" a map + filtering out the nil values was a TERRIBLE idea.


Elviro

> Il giorno 24 ott 2017, alle ore 00:15, Max Moiseev via swift-evolution 
>  ha scritto:
> 
> Hi swift-evolution!
> 
> I would like to propose the following change to the standard library:
> 
> deprecate `Sequence.flatMap(_: (Element) -> U?) -> [U]` and make this 
> functionality available under a new name `Sequence.filteredMap(_:)`.
> 
> The draft is available at 
> https://gist.github.com/moiseev/2f36376c8ef4c2b1273cff0bfd9c3b95 
>  and is 
> included below for your convenience.
> 
> Max
> 
> Introduce Sequence.filteredMap(_:)
> 
> Proposal: SE- 
> Authors: Max Moiseev 
> Review Manager: TBD
> Status: Awaiting implementation
>  
> Introduction
> 
> We propose to deprecate the controversial version of a Sequence.flatMap 
> method and provide the same functionality under a different, and potentially 
> more descriptive, name.
> 
>  
> Motivation
> 
> The Swift standard library currently defines 3 distinct overloads for flatMap:
> 
> Sequence.flatMap(_: (Element) -> S) -> [S.Element]
> where S : Sequence
> Optional.flatMap(_: (Wrapped) -> U?) -> U?
> Sequence.flatMap(_: (Element) -> U?) -> [U]
> The last one, despite being useful in certain situations, can be (and often 
> is) misused. Consider the following snippet:
> 
> struct Person {
>   var age: Int
>   var name: String
> }
> 
> func getAges(people: [Person]) -> [Int] {
>   return people.flatMap { $0.age }
> }
> What happens inside getNames is: thanks to the implicit promotion to 
> Optional, the result of the closure gets wrapped into a .some, then 
> immediately unwrapped by the implementation of flatMap, and appended to the 
> result array. All this unnecessary wrapping and unwrapping can be easily 
> avoided by just using map instead.
> 
> func getAges(people: [Person]) -> [Int] {
>   return people.map { $0.age }
> }
> It gets even worse when we consider future code modifications, like the one 
> where Swift 4 introduced a Stringconformance to the Collection protocol. The 
> following code used to compile (due to the flatMap overload in question).
> 
> func getNames(people: [Person]) -> [String] {
>   return people.flatMap { $0.name }
> }
> But it no longer does, because now there is a better overload that does not 
> involve implicit promotion. In this particular case, the compiler error would 
> be obvious, as it would point at the same line where flatMap is used. Imagine 
> however if it was just a let names = people.flatMap { $0.name } statement, 
> and the names variable were used elsewhere. The compiler error would be 
> misleading.
> 
>  
> Proposed
>  solution
> 
> We propose to deprecate the controversial overload of flatMap and 
> re-introduce the same functionality under a new name. The name being 
> filteredMap(_:) as we believe it best describes the intent of this function.
> 
> For reference, here are the alternative names from other languages:
> 
> Haskell, Idris 
> mapMaybe :: (a -> Maybe b) -> [a] -> [b]
> Ocaml (Core and Batteries)
>  filter_map : 'a t -> f:('a -> 'b option) -> 'b t
> F#
>  List.choose : ('T -> 'U option) -> 'T list -> 'U list
> Rust
>  fn filter_map(self, f: F) -> FilterMap
>  where F: 
> FnMut(Self::Item) -> Option
> Scala 
> def collect[B](pf: PartialFunction[A, B]): List[B]
>  
> Source
>  compatibility
> 
> Since the old function will still be available (although deprecated) all the 
> existing code will compile, producing a deprecation warning and a fix-it.
> 
>  
> Effect
>  on ABI stability
> 
> This is an additive API change, and does not affect ABI stability.
> 
>  
> Effect
>  on API resilience
> 
> Ideally, the deprecated flatMap overload would not exist at the time when ABI 
> stability is declared, but in the worst case, it will be available in a 
> deprecated form from a library post-ABI stability.
> 
>  
> Alternatives
>  considered
> 
> It was attempted in the past to warn about this kind of misuse and do the 
> right thing instead by means of a deprecated overload with a 
> non-optional-returning closure. The attempt failed due to another implicit 
> promotion (this time to Any).
> 
> The following alternative names for this function were considered:
> 
> mapNonNil(_:

Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-18 Thread Elviro Rocca via swift-evolution
I'm also available to help on the topic of pure functions, if you need any :)


Elviro


> I suggested a little while ago on this list some principles based on this 
> that would allow for the compiler to enforce value semantics with a `pure` 
> attribute and I'm currently working on a draft proposal. In essence this 
> proposal will have pure functions guaranteeing value semantics and no access 
> to the global state, and a correct implementation for copy-on-write types. I 
> think this would be useful for actors.
> 
> -- 
> Michel Fortin
> https://michelf.ca 

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


Re: [swift-evolution] [Concurrency] async/await + actors

2017-08-18 Thread Elviro Rocca via swift-evolution
Thanks a lot for this piece: it was a great read, that could serve as primer to 
most discussions about async programming in general, also thanks to the various 
links and references.

Here's my thoughts:

- You might have been too soft on the callback-based syntax of many Cocoa APIs: 
those are really bad, and in general a pain to use. Of course a import strategy 
for future Swift will be needed, but I wouldn't consider design constraints 
exclusively derived from some Cocoa APIs shortcomings, like 
URLSession.dataTask(withURL:completionHandler:) that I think can be safely 
ignored.

- I agree on the focus on async/await as compiler-level tools for defining and 
using coroutines, with Future and stuff like that to be considered as 
library functions built on top of the syntax: this way async/await doesn't 
become mere syntactic sugar.

- I really STRONGLY disagree on conflating async and throws: they are different 
things, and exist for different purposes, the same way as Future and 
Result are different things and should be usable separately. The right way 
to handle a "failable" future is to simply use a Future>, and 
eventually define convenience functions for the "success" and "failure" cases, 
or event methods on Future (in this case a ResultType protocol would be 
needed). It's a lot better to define simpler concepts that compose in 
interesting ways, rather than conflating unrelated things for minor 
conveniences.

- async/await is good, but the Actor model part is simply glorious :D

- I'm so happy that adding a native idiomatic Actor model has been considered 
for Swift, and I like the interplay with await for making actor functions 
return, as well as the progressive disclosure that can be achieved with more 
and more restrictive keywords: it even seems to me a real step-up from existing 
implementations of the model.

- in general I think that one of the best (if not the best) features of Swift 
is the idea of progressive disclosure, and that should be preserved... and I'm 
a fan of "actor class" :D

- I like the "ValueSemantical" protocol idea, but eventually I would like Swift 
to have features to actually enforce safe patterns though the language itself, 
like a "pure" or "safe" keyword: I almost use no classes (excluding the UIKit 
ones that I'm forced to use) and mostly write pure functions, but as the 
language forces me to do extra work when I'm dealing with an Optional or a 
throwing function, and that's a good thing in my opinion and facilitates my 
work as a software engineer, I would love a language that warned me that I'm 
accessing a potentially mutable instance with reference semantics in a context 
that I'm mistakenly considering as pure, or that the function I'm writing is 
not actually pure because a non-pure function was called inside it.

- I love the way the "actor" keyword for a method transforms it in an "inbox": 
I think the implementation you're proposing is super "Swifty" and could appear 
so convenient that many people could be drawn to the language just thanks to 
the great native concurrency model; I think that a powerful but simple and 
usable concurrency model is a heavy motivation for adopting a certain language 
in many contexts.


Thanks


Elviro

> Il giorno 18 ago 2017, alle ore 00:24, Chris Lattner via swift-evolution 
>  ha scritto:
> 
> Hi all,
> 
> As Ted mentioned in his email, it is great to finally kick off discussions 
> for what concurrency should look like in Swift.  This will surely be an epic 
> multi-year journey, but it is more important to find the right design than to 
> get there fast.
> 
> I’ve been advocating for a specific model involving async/await and actors 
> for many years now.  Handwaving only goes so far, so some folks asked me to 
> write them down to make the discussion more helpful and concrete.  While I 
> hope these ideas help push the discussion on concurrency forward, this isn’t 
> in any way meant to cut off other directions: in fact I hope it helps give 
> proponents of other designs a model to follow: a discussion giving extensive 
> rationale, combined with the long term story arc to show that the features 
> fit together.
> 
> Anyway, here is the document, I hope it is useful, and I’d love to hear 
> comments and suggestions for improvement:
> https://gist.github.com/lattner/31ed37682ef1576b16bca1432ea9f782
> 
> -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] [Review] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Elviro Rocca via swift-evolution
Huge +1

This should have been there from Swift 1, and basically forced me to use 
Sourcery to automatically generate all that code.


Elviro

> Il giorno 10 ago 2017, alle ore 01:09, Chris Lattner via swift-evolution 
>  ha scritto:
> 
> Hello Swift community,
> 
> The review of SE-0185 - "Synthesizing Equatable and Hashable conformance" 
> begins now and runs through August 15, 2017. The proposal is available here:
> https://github.com/apple/swift-evolution/blob/master/proposals/0185-synthesize-equatable-hashable.md
> 
> 
> Reviews are an important part of the Swift evolution process. All reviews 
> should be sent to the swift-evolution mailing list at:
> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> or, if you would like to keep your feedback private, directly to the review 
> manager. When replying, please try to keep the proposal link at the top of 
> the message:
> 
> What goes into a review?
> 
> The goal of the review process is to improve the proposal under review 
> through constructive criticism and, eventually, determine the direction of 
> Swift. When writing your review, here are some questions you might want to 
> answer in your review:
> 
>   • What is your evaluation of the proposal?
>   • Is the problem being addressed significant enough to warrant a change 
> to Swift?
>   • Does this proposal fit well with the feel and direction of Swift?
>   • If you have used other languages or libraries with a similar feature, 
> how do you feel that this proposal compares to those?
>   • How much effort did you put into your review? A glance, a quick 
> reading, or an in-depth study?
> 
> More information about the Swift evolution process is available at:
> https://github.com/apple/swift-evolution/blob/master/process.md
> 
> 
> Thank you,
> 
> Chris Lattner
> Review Manager
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Pitch] Improving unspecified generic usability

2017-08-08 Thread Elviro Rocca via swift-evolution
To my understanding, the following is exactly as it should be:

FooStruct as? FooStruct // Compiles but conversion fails, becomes 
nil, and that's normal

The reason for this is that FooStruct is not a subtype of 
FooStruct (or just FooStruct), while String is of course a subtype of Any, 
because generic types are not covariant in Swift, and that's the way it should 
be for a sound static type system. My comments on this were related to what you 
wrote about  arrays.

In theory a protocol without associated types could be synthesized for all the 
non generic properties and methods of a generic type, with the ability of 
casting to it and possibly from it.

It's a useful idea, and I'm all for it (I think literally everyone that uses 
generics and protocols with associated types encountered these kinds of 
problems at least once), I'm just saying that I'd rather work on generalized 
existentials which have already been considered by the core team, at least from 
a theoretical standpoint, have a greater scope and include cases like this. In 
general I tend to prefer broader, more generic solutions rooted in type theory 
when dealing with generics and protocols, but that's just me. 


Elviro


> Il giorno 08 ago 2017, alle ore 10:44, Logan Shire via swift-evolution 
>  ha scritto:
> 
> Thanks for the feedback!
> 
> Félix, sorry about the confusion between FooStruct and FooProtocol - I'll 
> refer to them as such moving forwards.
> 
> David, I don't believe you should be able to cast an [FooStruct] to 
> an [FooStruct] because those are both valid specifications. If 
> Generalized Existentials 
> 
>  are implemented, that would be another story, but that's outside the scope 
> of this proposal. I do believe you should be able to cast [FooStruct] 
> to [FooStruct], and that you should be able to flatMap [FooStruct] into 
> [FooStruct] with as?, but all of the casts would fail and you would be 
> left with an empty array.
> 
> In regards to the Named protocol, yes, that is the current idiomatic approach 
> to solving this problem (along with making a function unnecessarily generic 
> and then using the generic type as a constraint). I want to avoid jumping 
> through those hoops. We'd essentially be synthesizing the Named protocol with 
> the same name as the non-generic version of the type. I.e. FooStruct: 
> FooStruct
> 
> Félix, I believe the above answers some of your questions, but in regards to 
> protocols with associated types, I'd imagine it would work the same way. If 
> FooProtocol has an associated type T, there would be another protocol, 
> FooProtocol, without the associated type. (behind the scenes its garbled name 
> would be different)
> 
> Also, an aside, it would be nice if protocols could use the generic syntax 
> for their associated type constraints. I.e. "FooProtocol with T = Int" could 
> be expressed as FooProtocol. It feels strange that we have two 
> different syntaxes for essentially the same language construct. At the very 
> least, I want some way to cast a value to a protocol type with an associated 
> value. E.g. "if let grassEater = any as? Animal where Food = Grass"
> 
> Elviro, yes, the generalized existentials would help a lot here, but that's 
> outside the scope of what I'm proposing. In the near term I'd like to be able 
> to use a generic type's non-generic interface, casting to and from it. See 
> the above discussion regarding the Named protocol. Essentially we'd be 
> synthesizing the Named protocol, but where the type's name is the same as the 
> non-generic version of the type name.
> 
> FooStruct as FooStruct // works
> FooStruct as? FooStruct // works
> FooStruct as? FooStruct // Compiles but conversion fails, becomes nil
> FooStruct as? FooStruct // Compiles but conversion fails, 
> becomes nil
> 
> Let me know if you have any other questions!
> 
> Logan
> 
> 
> On Tue, Aug 8, 2017 at 9:43 AM Félix Cloutier  > wrote:
> I'm going to separate your examples into FooStruct and FooProtocol for 
> clarity.
> 
> I agree that generics tend to propagate virally and I remember that at some 
> point I wanted type erasure, though I don't remember for what exactly. The 
> solution for `sayHi`, right now, is to make that one generic too:
> 
>> func sayHi(to foo: T) where T: FooProtocol {
>> print("hi \(foo.name )")
>> }
> 
> The "let foos: [FooStruct] = [FooStruct(name: "Int", value: 2), 
> FooStruct(name: "Double", value: 2.0)]" part can't work for structs because 
> arrays require each element to have the same size (but it could work for 
> classes).
> 
> Even then, you couldn't infer the type to [FooClass] because 
> contravariance isn't permissible in that situation: doing so would allow you 
> to assign any Any to a FooClass's value.
> 
> Another problem that this would have to solve is that once you lose the 
> associatedtype 

Re: [swift-evolution] [Pitch] Improving unspecified generic usability

2017-08-08 Thread Elviro Rocca via swift-evolution
Covariant generic types make for an unsound type system. I believe the reason 
why Array and Optional are covariant in their generic parameter is that the way 
their implementation interacts with their internal storage assures that new 
storage is created if types mismatch: this means that to make covariance work 
for generic types you have to be extra careful when using references, because 
it doesn't really make sense from a mathematical standpoint (from my 
understanding of the matter).

What could probably be useful in your case is the concept of "generalized 
existential", which is considered in the generics manifesto ( 
https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#generalized-existentials
 

 ) and I believe is something that will eventually be added to Swift in the 
future because many use cases have come up in the mailing list over time: for 
example smart KeyPaths were implemented with classes instead of structs and 
protocols because of the lack of generalized existentials in the language.


Elviro   


> Il giorno 08 ago 2017, alle ore 00:00, Logan Shire via swift-evolution 
>  ha scritto:
> 
> One of my longstanding frustrations with generic types and protocols has been 
> how hard it is to work with them when their type is unspecified.
> Often I find myself wishing that I could write a function that takes a 
> generic type or protocol as a parameter, but doesn’t care what its generic 
> type is.
> 
> For example, if I have a type:
> 
> struct Foo {
> let name: String
> let value: T
> }
> 
> or:
> 
> protocol Foo {
> associatedtype T
> var name: String { get }
> var value: T { get }
> }
> 
> And I want to write a function that only cares about Foo.name, I’d like to be 
> able to:
> 
> func sayHi(to foo: Foo) {
> print("hi \(foo.name)")
> }
> 
> But instead I get the error, “Reference to generic type Foo requires 
> arguments in <…>”
> 
> Also, when you want to have a polymorphic array of generic types, you can’t:
> 
> let foos: [Foo] = [Foo(name: "Int", value: 2), Foo(name: "Double", value: 
> 2.0)]
> 
> And if you remove the explicit type coercion, you just get [Any]
> 
> let foos = [Foo(name: "Int", value: 2), Foo(name: "Double", value: 2.0)]
> 
> I wish that could be inferred to be [Foo]. I’d like to propose being able to 
> use the non-generic interface of a type normally. 
> I.e. if you have a type Foo, it is implicitly of type Foo as well. The 
> type Foo could be used like any other type.
> It could be a parameter in a function, a variable, or even the generic type 
> of another type (like a Dictionary)
> 
> The only restriction is that if you want to call or access, directly or 
> indirectly, a function or member that requires the generic type,
> the generic type would have to be known at that point.
> 
> Foo should be able to be implicitly casted to Foo wherever you want, and 
> Foo could be cast to Foo conditionally.
> Initializers would still obviously have to know the generic type, but given 
> the above example, you should be able to:
> 
> let names = foos.map { $0.name }
> 
> However, you could not do the following:
> 
> let foos = [Foo]()
> 
> Because the initializer would need to know the generic type in order to 
> allocate the memory.
> 
> Let me know what you think!
> 
> —
> 
> Logan Shire
> iOS @ Lyft
> 
> ___
> 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] [planning] [discussion] Schedule for return of closure parameter labels (+ world domination ramble)

2017-08-07 Thread Elviro Rocca via swift-evolution
I agree with everything you wrote, in particular I agree with the idea that it 
is more important to get the big efforts right, and that they should take 
priority. But I would consider a distinction:

- big efforts that add huge new features to the language so that things that 
were done in userland with libraries can be done natively and idiomatically 
(concurrent programming, for example);
- more "theoretical" big efforts, that allow one, while building a single app 
or a big library, to "express" more things more precisely in the language, and 
improvements to the generics and protocols systems fall in this second realm;

The reason why I consider the second kind of feature as more important than the 
first (thus, earning higher priority) is that, apart from reducing the amount 
of busywork to be done in many cases where the abstraction power is not good 
enough, it gives more tools for the community to build upon, it allows many 
people to do more with the language than probably me, you and the core team 
have ever though of, it fosters the explosion of creativity that's only 
possible when a language is expressive enough and it's not only based on 
certain conventions (that, by definition, constraint the way a language is 
commonly used).

What do you think?

Thanks


Elviro

> Il giorno 07 ago 2017, alle ore 18:11, Chris Lattner  ha 
> scritto:
> 
> 
>> On Aug 7, 2017, at 12:43 AM, Elviro Rocca  
>> wrote:
>> 
>> I read many times the "most users don't care about this" objection but I 
>> always considered it more like an argument for postponing something than 
>> removing it completely from the Swift equation (I believe I also read words 
>> like that from yourself, Chris), because there is a point about scheduling 
>> work to make the language more useful for more people faster. I'm still 
>> acting upon the belief that the Swift core team recognizes that the language 
>> still lacks a lot of absolutely basic and essential features, that every 
>> "power user" that pushes the boundaries of what Swift has to offer can't 
>> wait for to be added.
> 
> Yes, there is a really huge amount of stuff that is missing from Swift.  I 
> suspect my list is longer than anyone else’s. :-)
> 
> My point on this is that it is more important to get the big efforts right 
> than it is to over-prioritize the small efforts.  This is both because of 
> implementation bandwidth reasons, but more importantly because it leads to a 
> better design.  Big efforts are *hard*, and tend to be less driven by the 
> community at large, but they really should take priority.
> 
> If you’re into analogies, I see features like the generics improvements, 
> concurrency model, ownership system, macro system, ABI stability, new 
> frameworks, and other large scale efforts as the “bricks" that make up the 
> house of Swift.  In that analogy, smaller proposals are “mortar” that fills 
> in the cracks between the bricks.  If we add too much mortar too early on, we 
> run the risk of the house of Swift being built out of mortar, or of not being 
> able to fit the bricks into the right places.  That would be very bad, given 
> that we all want the house of Swift to be strong and beautiful over the long 
> term.
> 
> Clearly there is a balance to be made, which is why major Swift releases are 
> a mix of large efforts (e.g. Codable improvements, typed keypaths, String 
> redesign...) as well as smaller ones (e.g. multiline strings, dictionary API 
> improvements, etc).
> 
> -Chris
> 
> 

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


Re: [swift-evolution] [planning] [discussion] Schedule for return of closure parameter labels (+ world domination ramble)

2017-08-07 Thread Elviro Rocca via swift-evolution
I read many times the "most users don't care about this" objection but I always 
considered it more like an argument for postponing something than removing it 
completely from the Swift equation (I believe I also read words like that from 
yourself, Chris), because there is a point about scheduling work to make the 
language more useful for more people faster. I'm still acting upon the belief 
that the Swift core team recognizes that the language still lacks a lot of 
absolutely basic and essential features, that every "power user" that pushes 
the boundaries of what Swift has to offer can't wait for to be added.

I would argue that there are 2 kinds of features to be considered in the 
process of a language's evolution:

1) additions and improvements that augment the type/abstraction system and make 
the language itself more expressive;
2) utility tools like alternate declarations for identical concepts (like 
keywords that add some syntactic sugar) and enhancements to the standard 
library;

The difference between the two is the fact that the first allows users 
(including people that work on the standard library) to build better, more 
precise and sophisticated things with the language, while the second can make 
the language more useful and fun to use out-of-the-box by providing ready-made 
tools (for example, I'm glad that the standard library provides a "map" and 
"flatMap" for Optionals, and I 100% recognize the importance of syntactic sugar 
in many contexts, like for example keywords like async/await).

I would also argue that, while a prioritization strategy would probably favor 
the second type of features for the first years of a language's life, the 
effort in improving the language within the realm of the first type of features 
should still be constantly moving forward, along with everything else, if 
nothing because most of the second depends on the first.

For example, it we had conditional protocol conformances from the beginning 
(Swift 2), many aspects of the standard library and of many third-party library 
would be MASSIVELY different, and a lot of work of library-building would have 
been easier and faster.

I think these kinds of considerations are particularly important for Swift, 
because Swift is exactly the kind of language that can be molded to one 
developer's will, and doesn't overly push "conventions" like many more 
loosely-typed languages do: in a language as free to be interpreted as Swift, 
core features that enhance expressivity are, I think, the most important ones.

Thanks


Elviro


> Il giorno 04 ago 2017, alle ore 19:32, Chris Lattner via swift-evolution 
>  ha scritto:
> 
> 
>> On Aug 4, 2017, at 9:16 AM, Mathew Huusko V via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Per 
>> https://lists.swift.org/pipermail/swift-evolution-announce/2016-July/000233.html
>>  
>> ,
>>  the removal of parameter labels entirely was accepted as a temporary loss 
>> for Swift 3 as a means to remove them from the type system. I'm wondering if 
>> they're coming back (syntactically) any time soon?
> 
> The planning approach for Swift 5 hasn’t been announced yet, but it should be 
> soon-ish.
> 
> Responding to the rest of your email in broad terms: there will always be a 
> ton of things that are important and interesting to tackle.  There is also a 
> long road ahead of Swift, so prioritization is not a bad thing: just because 
> something doesn’t happen “now” doesn’t mean it never will.
> 
> I would also argue that it would be *bad* for the language to evolve too 
> fast.  Landing 20 major features all in the same year runs the very high risk 
> that they doesn’t work well together and don’t have time to settle out 
> properly.  It is far more important for Swift to be great over the long term 
> than to have any individual little feature “now”.
> 
> -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] Why you can't make someone else's class Decodable: a long-winded explanation of 'required' initializers

2017-08-03 Thread Elviro Rocca via swift-evolution
Wrapper structs FTW. I think it's a lovely pattern that's super Swifty and 
really should be advertised more for solving these kinds of problems. 
Language-level features could also be useful for making that more usable, and 
the discussion about "strong" typealiases seems oriented in that direction.


Elviro


> Il giorno 03 ago 2017, alle ore 08:35, David Hart via swift-evolution 
> mailto:swift-evolution@swift.org>> ha scritto:
> 
> 
>> On 3 Aug 2017, at 08:00, Slava Pestov > > wrote:
>> 
>> 
>> 
>>> On Aug 2, 2017, at 10:48 PM, David Hart >> > wrote:
>>> 
>>> Somewhat related: I have a similar problem in a project where I need two 
>>> different Codable conformances for a type: one for coding/decoding from/to 
>>> JSON, and another one for coding/decoding from/to a database row. The keys 
>>> and formatting are not identical. The only solution around that for now is 
>>> separate types, which can be sub-optimal from a performance point of view.
>> Actually if the wrapper types are structs with a single field, their use 
>> should not introduce any additional overhead at runtime.
> 
> I ❤️ Swift
> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution
>> Slava

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


Re: [swift-evolution] [Idea] Custom keywords for operators.

2017-08-01 Thread Elviro Rocca via swift-evolution
I understand the technical problem here, and killed my hope for "nominal" 
operators long time ago with fire.

But if someone here uses Kotlin, they know very well how great it is to be able 
to infix functions of 2 parameters like they were operators: it makes code 
extremely clean and readable, and it's extremely useful when writing DSLs.


Elviro


> Il giorno 01 ago 2017, alle ore 03:29, Chris Lattner via swift-evolution 
>  ha scritto:
> 
> 
>> On Jul 31, 2017, at 2:09 PM, Gor Gyolchanyan via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> So I was thinking the other day (and by "the other day" I mean "It just 
>> occurred to me") that Swift's custom operator declaration mechanism is 
>> pretty sweet (it's become even sweeter ever since numeric precedence values 
>> were replaced with purely relativistic precedence trees). There are 
>> currently only two problems with them that grind my operator-declaring 
>> endeavors to a painful halt:
>>  1. The fact that most punctuation characters on the keyboard (think - 
>> ASCII) are reserved, so any custom operator either has to be a long sequence 
>> of two or three non-reserved ASCII characters or have to include 
>> difficult-to-type unicode punctuation characters.
>>  2. The fact that anything that passes as an identifier character (which 
>> includes a surprisingly wide array of punctuation characters) is off the 
>> table as well.
> 
> See the 3rd entry of:
> https://github.com/apple/swift-evolution/blob/master/commonly_proposed.md 
> 
> 
> -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] [Pitch] Small bit of sugar for enum case with Void associated value

2017-07-26 Thread Elviro Rocca via swift-evolution
+1 to this

I not only support the case in question, but I 100% support any proposal that 
would push to compiler to completely remove any distinction from isomorphic 
tuples, by always reducing the tuple to the simplest form (this kind of 
discussion also took place in the thread about the SE110 rollback).

In case of:


enum Foo {
case bar(T)
case baz()
}


if Foo.bar is to be considered a function of type "(T) -> Foo", and 
Foo.baz a function of type "() -> Foo", then when "T == ()" the two 
function must be considered of the same type, and there's no real reason from 
the user standpoint to consider them of different type.

And not just that, because in the case of:


enum Foo {
case bar(Int,T)
case baz()
}


if "T == ()" the two functions should be respectively of type "(Int) -> 
Foo<()>" and "() -> Foo<()>", while the first one is currently of type 
"(Int,()) -> Foo<()>" which makes absolutely no sense.

A function that has a value of type "()" in the inputs makes no sense at all. 
The following function signature is meaningless and its avoidance should be 
enforced by the compiler


func wat(_ value: ()) -> Int {
return 42
}

let a = wat

let b = a() /// compiler error


The empty tuple should be automatically removed by the compiler for generics, 
or an error should be emitted in non-generic cases, simply because it is a 
singleton and it can always be produced out of thin air. It shouldn't be a 
valid argument of a function, and it should be stripped by any tuple like 
"(A,(),B)" or similar.

I made several more points in the SE110 discussion, and answered to most of the 
objections, so if you're interested you can read my answers there.


Thanks


Elviro


 

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


Re: [swift-evolution] [Pitch] KeyPath based map, flatMap, filter

2017-07-17 Thread Elviro Rocca via swift-evolution
Subscripts in Swift in fact have always looked to me like a way to make objects 
"callable", where you use brackets instead of parentheses: the difference of 
course is the fact that, when used point-free, the object will be considered an 
instance and not a function.

In this sense we could theoretically make a KeyPath callable by adding 
subscripts; consider the following code:


extension KeyPath {
subscript (get root: Root) -> Value {
return root[keyPath: self]
}
}

struct Person {
var firstName: String
var lastName: String
}

let x = Person.init(firstName: "Foo", lastName: "Bar")

let foo = (\Person.firstName)[get: x] /// "Foo"


This is valid Swift code (Swift 4.0 snapshot 2017-07-13). In theory a possible 
evolution of this could be referencing the subscript function in a point-free 
way like we can already do with regular functions:


let callable1 = (\Person.firstName)[get:] /// this won't compile


For the setter part, because the other half of a KeyPath is essentially a 
function of type (Value, inout Root) -> (), we could theoretically considering 
this kind of subscript function:


extension KeyPath {
subscript (set value: Value, on root: inout Root) -> () { /// this 
won't compile
root[keyPath: self] = value
return ()
}
}

let callable2 = (\Person.firstName)[set:,on:] /// this won't compile


But we cannot write subscripts with inout parameters. I actually find the 
subscript path a very interesting one to consider, but there's still a lot of 
machinery that's missing.

I would prefer two standardized prefix operators - for extracting the "(Root) 
-> Value" and the "(Value,inout Root) -> ()" parts of a KeyPath - to be added 
to the standard library. This is exactly the case where custom operators make 
sense: repeated operations that should be expressed with minimum code noise.


Elviro

> Il giorno 16 lug 2017, alle ore 18:34, Benjamin Herzog via swift-evolution 
>  ha scritto:
> 
> If it would be possible to make objects callable, wouldn't that also go
> in the same direction as subscripts currently? One could also implement
> it with the syntax for callable functions (in this case anonymous -
> without a name). Instead of this:
> 
> subscript(index: Int) -> T
> 
> we could also write
> 
> func (_ index: Int) -> T
> 
> On the call side it would change from this:
> 
> list[3] to list(3)
> 
> I know that it's not necessary and not even better readable, but it goes
> in the same direction in my opinion and is worth considering. What do
> you think?
> 
> __
> 
> Benjamin Herzog
> 
> On Wed, Jul 12, 2017, at 10:21 PM, Dave Abrahams via swift-evolution
> wrote:
>> 
>> on Tue Jul 11 2017, Robert Bennett  wrote:
>> 
>>> Just realized that even inout functions don’t let you do
>>> member(object) = value. 
>> 
>> The other difference is that an inout function can't be used to get a
>> member from an immutable value, whereas a keypath/subscript/property
>> access can.
>> 
>> 
>> -- 
>> -Dave
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Pitch] KeyPath based map, flatMap, filter

2017-07-11 Thread Elviro Rocca via swift-evolution
Overloads are ugly. The very existence of an overloaded function usually means 
a lack of available abstractions, or an insufficient abstraction power in the 
language: exhibit A is conditional conformances to protocols.

Overloads are particularly ugly if the overloaded function's input represents 
basically the same thing: a KeyPath is really (semantically) just a couple 
of functions, that is, (A) -> B and (inout A,B) -> (), so the (A) -> B is 
already there, and I like the idea of an "extraction" operator that was 
proposed in the thread. It would be really interesting to just use the 
KeyPath itself wherever a (A) -> B is required, but this looks like a hack 
given the current state of Swift's type system.

But I like the fundamental idea behind the proposal: KeyPaths give Swift a 
boost in expressive power, and there's probably plenty of use cases that will 
emerge in the future.

Thanks


Elviro

> Il giorno 05 lug 2017, alle ore 19:08, Benjamin Herzog via swift-evolution 
>  ha scritto:
> 
> Hey guys,
> 
> I would like to pitch a small convenient change to the Swift stdlib. With 
> KeyPaths added in SE-0161 I would like to add some convenience calls to map, 
> flatMap and filter in Sequences. To extract properties of an array of objects 
> we currently use trailing closure syntax together with the shorthand $0 for 
> the first closure argument. This is still kind of verbose and also hard to 
> read in some situations.
> I think it is much better to understand what is going on when using the type 
> safe KeyPaths for that. I already implemented a working solution and would 
> like to pitch the idea here to get some feedback before opening the swift 
> evolution proposal.
> I propose using 
> 
> persons.flatMap(keyPath: \.name)
> 
> over
> 
> persons.flatMap { $0.name }
> 
> Link to pull request: https://github.com/apple/swift/pull/10760 
> 
> 
> Link to proposal draft: 
> https://github.com/BenchR267/swift-evolution/blob/keypath-based-map/proposals/0181-keypath-based-map-flatmap-filter.md
>  
> 
> 
> Thanks in advance for your feedback!
> __
> 
> Benjamin Herzog
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [Pitch] Guard/Catch

2017-07-11 Thread Elviro Rocca via swift-evolution
Not sure what you mean here. A guard/catch would allow me to handle the error 
in the catch, something that (of course) cannot be done with "try?", so 
guard/else with "try?" is not a solution. And of course returning in the catch 
side of a do/catch is like returning in the else side of a if/else, but that's 
what "guard" is about, so I probably didn't understand what's your point here.


Elviro


> Il giorno 11 lug 2017, alle ore 01:10, Christopher Kornher  
> ha scritto:
> 
> FYI this works today in Xcode 9.0 beta 2 playgrounds:
> 
> ```
> class X {
> init() throws {}
> 
> func foo() {
> print( "Things succeeded" )
> }
> }
> 
> func bar() throws -> X  { return try X() }
> 
> 
> func f()
> {
> guard let x1:X = try? X(), let x2:X = try? bar() else {
> print( "Things failed ")
> return
> }
> 
> x1.foo()
> x2.foo()
> }
> 
> f()// works
> ```
> 
> So the only unhandled case is a non-returning throwing function or init:
>  
> ```
> class X {
> init() throws {}
> 
> func foo() {
> print( "Things succeeded" )
> }
> }
> 
> func bar() throws{ let _ =  try X() }
> 
> 
> func f()
> {
> do {
> try bar()
> } catch {
> return
> }
> 
> guard let x:X = try? X() else {
> print( "Things failed ")
> return
> }
> 
> x.foo()
> }
> 
> f()// works
> ```
> 
> Having to call a throwing, Void method before performing the rest of a 
> function seems like an edge case to me 
> 
> 
>> On Jul 10, 2017, at 1:45 AM, Elviro Rocca via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> This is not a sugar proposal, in the same way as "guard" is not syntactic 
>> sugar, because it requires exiting the scope on the else branch, adding 
>> expressive power and safety to the call: also, the sugary part is pretty 
>> important because it avoids nested parentheses and very clearly states that 
>> if the guard condition is not fulfilled, the execution will not reach the 
>> next lines of code. Guard is useful to push the programmer to at least 
>> consider an early return instead of branching code paths, to achieve better 
>> clarity, readability and lower complexity, and I suspect is one of the best 
>> Swift features for many people.
>> 
>> Also, the case that the proposal aims to cover is not an edge case at all 
>> for a lot of people, including me. Rethrowing an error is something that I 
>> almost never do, and I consider the "umbrella" do/catch at the top of the 
>> call stack an anti-pattern, but I understand that many people like it and 
>> I'm not arguing against it. I am arguing in favor of having options and not 
>> pushing a particular style onto programmers, and for my (and many people's) 
>> style, a guard/catch with forced return is an excellent idea. In fact you 
>> seem to agree on the necessity of some kind of forced-returnish catch but 
>> your elaborations don't seem (to me) much better than the proposal itself.
>> 
>> Dave DeLong raised the point of weird behavior in the case of a function 
>> like:
>> 
>> 
>> func doSomething() throws → Result? { … }
>> 
>> 
>> In this case, what would the type of x be?
>> 
>> 
>> guard let x = try doSomething() catch { /// handle and return }
>> 
>> 
>> Simple, it would be Optional. I don't find this confusing at all, 
>> and if the idea that just by seeing "guard let" we should expect a 
>> non-Optional is somehow diffused, I think it's better to eradicate it.
>> 
>> First of all, if I'm returning an optional from a throwing function, it's 
>> probably the case that I want the Optional to be there in the returned 
>> value: the only reason why I would consider doing that is if the semantics 
>> of Optional are pretty meaningful in that case. For example, when parsing a 
>> JSON in which I expect a String or null to be at a certain key:
>> 
>> 
>> extension String: Error {}
>> 
>> func parseString(in dict: [String:Any], at key: String) throws -> String? {
>>  guard let x = dict[key] else { throw "No value found at '\(key)' in 
>> \(dict)" }
>>  if let x = x as? String { return x }
>>  if let x = x as? NSNull { return nil }
>>  throw "Value at '\(key)' in \(dict) is not 'string' or &#x

Re: [swift-evolution] [Pitch] Guard/Catch

2017-07-10 Thread Elviro Rocca via swift-evolution
I don't think that "guard let x? = ..." would be syntactically correct, AFAIK 
for matching the pattern "let x? =", as for any other pattern, you need to use 
"case", in fact the following is perfectly valid:

guard case let x? = doSomething() else {
// handle when nil
}

I think that "guard let x =" is in fact sugar for "guard case let x? =", so 
your example should really be:

guard case let x? = try doSomething() catch {
// handle error
} else {
// handle when nil
}

This would basically mean "add an extra catch when pattern-matching with a 
throwing function", same as:

switch try doSomething() {
case let x?:
// handle
case nil:
// handle   
} catch {
// handle
}

Honestly I'm still not sold in conflating the two things. I don't think it 
would be problematic to clearly separate cases when I'm binding the result of a 
throwing function (which in fact is isomorphic to a Either) and 
binding an Optional.


Elviro

> Il giorno 10 lug 2017, alle ore 10:44, David Hart  ha 
> scritto:
> 
>> 
>> On 10 Jul 2017, at 09:45, Elviro Rocca via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> This is not a sugar proposal, in the same way as "guard" is not syntactic 
>> sugar, because it requires exiting the scope on the else branch, adding 
>> expressive power and safety to the call: also, the sugary part is pretty 
>> important because it avoids nested parentheses and very clearly states that 
>> if the guard condition is not fulfilled, the execution will not reach the 
>> next lines of code. Guard is useful to push the programmer to at least 
>> consider an early return instead of branching code paths, to achieve better 
>> clarity, readability and lower complexity, and I suspect is one of the best 
>> Swift features for many people.
>> 
>> Also, the case that the proposal aims to cover is not an edge case at all 
>> for a lot of people, including me. Rethrowing an error is something that I 
>> almost never do, and I consider the "umbrella" do/catch at the top of the 
>> call stack an anti-pattern, but I understand that many people like it and 
>> I'm not arguing against it. I am arguing in favor of having options and not 
>> pushing a particular style onto programmers, and for my (and many people's) 
>> style, a guard/catch with forced return is an excellent idea. In fact you 
>> seem to agree on the necessity of some kind of forced-returnish catch but 
>> your elaborations don't seem (to me) much better than the proposal itself.
>> 
>> Dave DeLong raised the point of weird behavior in the case of a function 
>> like:
>> 
>> 
>> func doSomething() throws → Result? { … }
>> 
>> 
>> In this case, what would the type of x be?
>> 
>> 
>> guard let x = try doSomething() catch { /// handle and return }
> 
> I know we can’t do much about it now, but if optional binding had used the 
> same syntax as it does in pattern matching, we wouldn’t be having this 
> discussion:
> 
> guard let x = try doSomething() catch {
> // handle error
> }
> 
> guard let x? = doSomething() else {
> // handle when nil
> }
> 
> And mixing both would be a bit cleaner because the ? would make it explicit 
> we are doing optional binding:
> 
> guard let x? = try doSomething() catch {
> // handle error
> } else {
> // handle when nil
> }
> 
>> Simple, it would be Optional. I don't find this confusing at all, 
>> and if the idea that just by seeing "guard let" we should expect a 
>> non-Optional is somehow diffused, I think it's better to eradicate it.
>> 
>> First of all, if I'm returning an optional from a throwing function, it's 
>> probably the case that I want the Optional to be there in the returned 
>> value: the only reason why I would consider doing that is if the semantics 
>> of Optional are pretty meaningful in that case. For example, when parsing a 
>> JSON in which I expect a String or null to be at a certain key:
>> 
>> 
>> extension String: Error {}
>> 
>> func parseString(in dict: [String:Any], at key: String) throws -> String? {
>>  guard let x = dict[key] else { throw "No value found at '\(key)' in 
>> \(dict)" }
>>  if let x = x as? String { return x }
>>  if let x = x as? NSNull { return nil }
>>  throw "Value at '\(key)' in \(dict) is not 'string' or 'null"
>> }
>> 
>> 
>> Thus, if I'm returning an Optional 

Re: [swift-evolution] [Pitch] Guard/Catch

2017-07-10 Thread Elviro Rocca via swift-evolution
This is not a sugar proposal, in the same way as "guard" is not syntactic 
sugar, because it requires exiting the scope on the else branch, adding 
expressive power and safety to the call: also, the sugary part is pretty 
important because it avoids nested parentheses and very clearly states that if 
the guard condition is not fulfilled, the execution will not reach the next 
lines of code. Guard is useful to push the programmer to at least consider an 
early return instead of branching code paths, to achieve better clarity, 
readability and lower complexity, and I suspect is one of the best Swift 
features for many people.

Also, the case that the proposal aims to cover is not an edge case at all for a 
lot of people, including me. Rethrowing an error is something that I almost 
never do, and I consider the "umbrella" do/catch at the top of the call stack 
an anti-pattern, but I understand that many people like it and I'm not arguing 
against it. I am arguing in favor of having options and not pushing a 
particular style onto programmers, and for my (and many people's) style, a 
guard/catch with forced return is an excellent idea. In fact you seem to agree 
on the necessity of some kind of forced-returnish catch but your elaborations 
don't seem (to me) much better than the proposal itself.

Dave DeLong raised the point of weird behavior in the case of a function like:


func doSomething() throws → Result? { … }


In this case, what would the type of x be?


guard let x = try doSomething() catch { /// handle and return }


Simple, it would be Optional. I don't find this confusing at all, and 
if the idea that just by seeing "guard let" we should expect a non-Optional is 
somehow diffused, I think it's better to eradicate it.

First of all, if I'm returning an optional from a throwing function, it's 
probably the case that I want the Optional to be there in the returned value: 
the only reason why I would consider doing that is if the semantics of Optional 
are pretty meaningful in that case. For example, when parsing a JSON in which I 
expect a String or null to be at a certain key:


extension String: Error {}

func parseString(in dict: [String:Any], at key: String) throws -> String? {
guard let x = dict[key] else { throw "No value found at '\(key)' in 
\(dict)" }
if let x = x as? String { return x }
if let x = x as? NSNull { return nil }
throw "Value at '\(key)' in \(dict) is not 'string' or 'null"
}


Thus, if I'm returning an Optional from a throwing function it means that I 
want to clearly distinguish the two cases, so they shouldn't be collapsed in a 
single call:


guard let x = try doSomething() catch { /// handle and return }
guard let x = x else { /// handle and return }


Also, if a function returns something like "Int??", a guard-let (or if-let) on 
the returned value of that function will still bind an "Int?", thus unwrapping 
only "one level" of optional. If-let and guard-let, as of today, just unwrap a 
single optional level, an do not guaranteed at all that the bound value is not 
optional.

To me guard-let (like if-let) is basically sugar for monadic binding for 
Optionals, with the additional expressivity granted by the forced return. I 
would love to see the same monadic binding structure applied to throwing 
functions.



Elviro



> Il giorno 09 lug 2017, alle ore 01:16, Christopher Kornher via 
> swift-evolution  > ha scritto:
> 
> Thanks for you considerate reply. My concern over the proliferation of “sugar 
> proposals” is a general one. This proposal has more merit and general 
> utiliity than many others. I have never used a throwing function in a guard 
> statement that was not itself in a throwing function, but I can see that it 
> could possibly be common in some code. Wrapping a guard statement and all the 
> code that uses variables set in the guard in a do/catch is sub-optimal.
> 
>> On Jul 8, 2017, at 4:16 PM, Benjamin Spratling via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> 
>> 
>> I’ve read your email, but haven’t digested it fully.  One thing I agree with 
>> is that most functions which call throwing functions don’t actually use a 
>> do…catch block, but instead are merely marked “throws” and the error is 
>> propagated back through the stack.  Once I seriously started coding 
>> functions with errors, I realized I almost always wanted my errors to reach 
>> my view-controller or my business logic so I could present separate UI if a 
>> real error occurred, and often my error message depended on the details of 
>> the error instance.
>> 
>> 
>> 
>> I disagree with your conclusion on this point.
>> The “guard” syntax is specifically designed to achieve early return (and 
>> placing code associated with early return at the point where it happens) and 
>> cleanly installing the returned value into the surrounding scope.  So far it 
>> has been used to achieve early return only wit

Re: [swift-evolution] [Pitch] Guard/Catch

2017-07-07 Thread Elviro Rocca via swift-evolution
Amazing proposal, I love it and thinking back there's plenty of times where I 
would have used the guard-catch instead of the non-swifty (to me) do-catch. A 
guard-catch construct still allows to handle errors explicitly, with the added 
convenience of forcing a return inside the catch, which is basically 100% of 
the cases for me. It's consistent with the semantics of "guard", that is, 
instead of indenting, exit the scope in the "negative" case.

I do not agree in mixing guard-catch with optional binding (+ bool conditions). 
I think it's clearer to keep the two separated, since you can always:

guard let x = try throwingFunction() catch { ... }
guard let y = x.optionalProperty, y == 42 else { ... }


Thanks


Elviro

> Il giorno 05 lug 2017, alle ore 19:40, Soroush Khanlou via swift-evolution 
> mailto:swift-evolution@swift.org>> ha scritto:
> 
> I’d like to propose a guard/catch construct to the language. It would allow 
> code to use throwing functions and handle errors fully, without straying from 
> a happy path. do/catch can be a bit heavy-handed sometimes, and it would be 
> nice to be able to handle throwing functions without committing to all the 
> nesting and ceremony of do/catch.
> 
> Full proposal, which discusses all the corner cases and alternatives:
> https://gist.github.com/khanlou/8bd9c6f46e2b3d94f0e9f037c775f5b9 
> 
> 
> Looking forward to feedback!
> 
> Soroush
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

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


Re: [swift-evolution] [Pitch] Introducing the "Unwrap or Die" operator to the standard library

2017-06-30 Thread Elviro Rocca via swift-evolution
Even if ?? is generally assumed as safe, fatalError would be there to clearly 
assert what's going on. This is true in general for fatalError, which presence 
in some code simply means that something could go wrong there, so the regular 
compilation-level safety cannot be a given. And as forced unwrapping, 
fatalError - and other failures caused by a precondition - is not something 
that should be used lightly.

I think that "?? fatalError()" clearly conveys the meaning, is future-proof and 
could be adopted as a best practice.


Elviro  

> Il giorno 30 giu 2017, alle ore 17:39, Jacob Williams via swift-evolution 
>  ha scritto:
> 
> I have been persuaded that extending the capabilities of the current ?? 
> operator has far more advantages than adding a new limited !! operator. While 
> I initially did not like the usage of the generally-assumed-safe ? for 
> throwing operations, the clarity provided by having to explicitly state your 
> ‘fatalError’ or ‘preconditionFailure’ etc, does make it obvious about what is 
> going on. 
> 
> Also, considering how this capability would eventually be possible with ?? 
> anyways once Never become a true bottom type, it does not make sense to add a 
> new operator that would essentially become deprecated in a short matter of 
> time anyways. As many people have stated, the bar for additions to the Swift 
> language should be, and is, exceptionally high. There just aren’t enough 
> pro’s for the !! operator to make it worthwhile.
> 
>> On Jun 30, 2017, at 9:31 AM, Erica Sadun via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> These are all excellent points. I also feel they sidestep the motivation of 
>> the proposal. Even if there were a bottom `Never` and you could use `?? 
>> fatalError()`, I still think the language would benefit from `!!`.
>> 
>> As the language is right now, you can write your own "or die" function using 
>> a `guard` statement, overloading `??`, or implementing `!!`. Being able to 
>> duplicate an explanatory fail path isn't the point. Offering a 
>> best-practices alternative to `!!` that is easy to use, obvious to 
>> understand, and simple to adopt is.
>> 
>> As for the `#line` and `#file` issue, that is my biggest concern but I 
>> believe that can be surmounted.
>> 
>> -- E
>> 
>> 
>> 
>>> On Jun 29, 2017, at 11:23 PM, Brent Royal-Gordon >> > wrote:
>>> 
 On Jun 27, 2017, at 10:16 AM, Erica Sadun via swift-evolution 
 mailto:swift-evolution@swift.org>> wrote:
 
 Using an operator to provide feedback on the context of a failed unwrap 
 has become a commonly implemented approach in the Swift developer 
 Community. What are your thoughts about adopting this widely-used operator 
 into the standard library?
 
 guard !lastItem.isEmpty else { return }
 let lastItem = array.last !! "Array must be non-empty"
 
 Details here:  
 https://gist.github.com/erica/423e4b1c63b95c4c90338cdff4939a9b 
 
 
 Thank you for your thoughtful feedback, -- E
>>> 
>>> Finally found a few minutes to read this thread.
>>> 
>>> I'm a big fan of the `Never`-based approach. (I was before, but I am more 
>>> so now.) Here are the points I can see in its favor:
>>> 
>>> 1. It is extremely clear about what's happening—`!!` is another random 
>>> operator to learn, but `fatalError(_:)` or `preconditionFailure(_:)` are 
>>> fairly self-explanatory, and `??` is something you might already be using.
>>> 
>>> 2. It allows you to control the optimization behavior by using 
>>> `fatalError`, `preconditionFailure`, or `assertionFailure` as desired.
>>> 
>>> 3. If we later change `throw` from being a statement to being a 
>>> `Never`-returning expression, you could use `throw` on the right-hand side 
>>> of `??`.
>>> 
>>> 4. It supports other `Never`-returning operations, like `abort()` or 
>>> `exit(_:)` or your custom `usage()` function, on the right side of `??`.
>>> 
>>> 5. It supports file-and-line error reporting without having to add any new 
>>> features; `!!` could not do this because an operator can't have extra, 
>>> defaulted parameters to carry the file and line.
>>> 
>>> 6. It harmonizes with the eventual idea of making `Never` a universal 
>>> bottom type, but we don't actually have to implement that today, because we 
>>> can just overload `??` for now.
>>> 
>>> Against these advantages, the only one I can see for `!!` is that it is 
>>> terse. Terseness is good, especially for a feature which is competing with 
>>> the single-character postfix `!` operator, but I can't help but be drawn to 
>>> the flexibility and power of `??` with a `Never` expression on the 
>>> right-hand side.
>>> 
>>> -- 
>>> Brent Royal-Gordon
>>> Architechies
>>> 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org 
>> 

Re: [swift-evolution] [Pitch] Introducing the "Unwrap or Die" operator to the standard library

2017-06-30 Thread Elviro Rocca via swift-evolution
100% agree with everything. A custom operator is a good idea for operations 
that are actually frequent: once you learn what it means, it really helps 
reduce noise in code and improve readability. But forced unwrapping is 
something that's intended to be used sparsely.


Elviro


> Il giorno 30 giu 2017, alle ore 10:15, Víctor Pimentel Rodríguez via 
> swift-evolution  ha scritto:
> 
> On Fri, Jun 30, 2017 at 7:24 AM, Brent Royal-Gordon via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
>> On Jun 27, 2017, at 10:16 AM, Erica Sadun via swift-evolution 
>> mailto:swift-evolution@swift.org>> wrote:
>> 
>> Using an operator to provide feedback on the context of a failed unwrap has 
>> become a commonly implemented approach in the Swift developer Community. 
>> What are your thoughts about adopting this widely-used operator into the 
>> standard library?
>> 
>> guard !lastItem.isEmpty else { return }
>> let lastItem = array.last !! "Array must be non-empty"
>> 
>> Details here:  
>> https://gist.github.com/erica/423e4b1c63b95c4c90338cdff4939a9b 
>> 
>> 
>> Thank you for your thoughtful feedback, -- E
> 
> Finally found a few minutes to read this thread.
> 
> I'm a big fan of the `Never`-based approach. (I was before, but I am more so 
> now.) Here are the points I can see in its favor:
> 
> 1. It is extremely clear about what's happening—`!!` is another random 
> operator to learn, but `fatalError(_:)` or `preconditionFailure(_:)` are 
> fairly self-explanatory, and `??` is something you might already be using.
> 
> 2. It allows you to control the optimization behavior by using `fatalError`, 
> `preconditionFailure`, or `assertionFailure` as desired.
> 
> 3. If we later change `throw` from being a statement to being a 
> `Never`-returning expression, you could use `throw` on the right-hand side of 
> `??`.
> 
> 4. It supports other `Never`-returning operations, like `abort()` or 
> `exit(_:)` or your custom `usage()` function, on the right side of `??`.
> 
> 5. It supports file-and-line error reporting without having to add any new 
> features; `!!` could not do this because an operator can't have extra, 
> defaulted parameters to carry the file and line.
> 
> 6. It harmonizes with the eventual idea of making `Never` a universal bottom 
> type, but we don't actually have to implement that today, because we can just 
> overload `??` for now.
> 
> Against these advantages, the only one I can see for `!!` is that it is 
> terse. Terseness is good, especially for a feature which is competing with 
> the single-character postfix `!` operator, but I can't help but be drawn to 
> the flexibility and power of `??` with a `Never` expression on the right-hand 
> side.
> 
> +1 to everything.
> 
> If terseness is the only clear advantage of a new operator that is meant to 
> be used sparsely, it's clear to me that the ?? Never form is better for the 
> Swift community as a whole.
> 
> --
> Víctor Pimentel
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Introducing the "Unwrap or Die" operator to the standard library

2017-06-29 Thread Elviro Rocca via swift-evolution

> Well, a persisted inconsistency is worse than a crash :P

I still strongly disagree with this, I'm sorry. Inconsistent data is an 
orthogonal problem to fatal errors, and a crash is basically a middle finger to 
the user. 

> To me this !! operator does not add enough value to put it in the standard 
> library. The existing force unwrap operator already works fine, and if Never 
> is really going to be a bottom type, then I don't know in which cases the !! 
> operator would be better.
> 
> Actually, for me it would be worse, because you could only call it with a 
> String or a function that returned a String. What happens if I want to call a 
> method that does some housekeeping and then ends with a fatalError? I could 
> not use the !! operator unless that method returns a String.
> 
> And finally, I would not want to find such code in a project with multiple 
> people involved, as my personal experience is that a single ! leads to 
> crashes in production sooner or later, and if you track such crashes it would 
> not be obvious why they happen. If that code is written by one person and 
> will not be published anywhere, I suppose you can use it, but either in open 
> source projects or in teams, I would avoid that operator like hell.
> 
> Instead of writing this (the original example, which by the way has a typo 
> :P):
> 
> guard !lastItem.isEmpty else { return }
> let lastItem = array.last !! "Array must be non-empty"
> 
> I would just write this:
> 
> guard let lastItem = array.last else { return }
> 
> The first example seems reasonable enough: you know that the array is empty, 
> you just checked for it! But that array may possible be a property of a class 
> and it can be changed in another thread, so you can't be so sure. And because 
> software is usually never finished, some other team mate can add more code 
> between the first line and the second line, making it easier to inadvertently 
> change the array contents and thus not preserving the initial invariants. The 
> second example may need to be rewritten if the requirements change, but it 
> does not have the same drawbacks as the initial example and, well, it's 
> definitely less code and easier to read.
> 
> Anyway, can we provide a real world example? If some projects are already 
> defining this operator, working examples must exist and we can analyze how 
> this operator affects the code and which patterns are leveraged by it.
> 

I agree with most of this, but I think the contraposition here is with:

guard let lastItem = array.last else { fatalError() }

> I understand your wish to never crash in production. But I think it’s an 
> ideal that is quite far from the day to day development practices of many 
> developers. If the philosophy of the Standard Library was to avoid all 
> production crashes, we wouldn’t have the following:
> 
> Implicitly unwrapped optionals
> Optional explicit unwrapping
> fatalError
> precondition
> 
> The fact is that we have those tools and that they are useful and used. I 
> salute your wish to ban all of the above in an effort to avoid all crashes in 
> production, but IMHO, it’s a style that is best enforced using a linter.

Swift is a language that doesn't enforce a particular style over the other 
(thankfully) so the standard library includes many constructs that can end up 
being mostly ignored by some people in some projects.

Because of that, I don't think that we should add to the standard library a 
particular construct just because some people use it in third party libraries, 
if the same behavior can be already accomplished with very minimal code using 
what's already there.

Also, avoiding all crashes in production is to me a fundamental value of 
software development, and is not particularly related to Swift or iOS or 
whatever. In fact, as was already written some posts before, logic errors are 
either mistakes or are used to avoid additional checks in cases when the 
overhead introduced by those checks is not acceptable from a performance 
standpoint, which is a very unfrequent case.

Now, during development I can decide to make something crash for informative 
reasons, so in general I'm not opposed at all to those constructs, but that 
doesn't justify production code that crashes due to implicit unwrapping or 
out-of-bounds errors. That's my opinion, and it's also my opinion that trusting 
a linter is a much weaker solution than actually enforcing the type-system and 
the compiler, and I'd say that Swift is not Objective-C or PHP, but that's a 
completely different topic.

Elviro

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


Re: [swift-evolution] [Pitch] Introducing the "Unwrap or Die" operator to the standard library

2017-06-29 Thread Elviro Rocca via swift-evolution
>From the user's standpoint, a crash is the worst thing possible, and should 
>always be avoided. A failure doesn't need to be silent for user, the app can 
>still communicate that there was an error with some kind of human readable 
>message, and the developer can still be informed via any service that provides 
>logging of non-fatal errors (there are many, most of them free).

During development, a crash can be informative, and that's what "assert" and 
things like that are for: even if I still prefer to not crash, and handle 
invariants by using specifically crafted types, I can understand the need for 
crashing in development, and from that standpoint I'd definitely support a 
proposal which goal is to make crashes caused by forced unwrapping more 
informative for the developer, or to force the developer to make them more 
informative (by substituting "!" with "!!").

The reason why I'm not completely convinced is the fact that there's already 
"fatalError", and its presence already clearly indicates in the code that 
something could trap there, in a verbally-appropriate way. In this sense a new 
operator could encourage practices that in my opinion should not be encouraged.


Elviro

> Il giorno 29 giu 2017, alle ore 12:12, David Hart  ha 
> scritto:
> 
> 
> 
> On 29 Jun 2017, at 09:19, Elviro Rocca via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
> 
>> 
>>> Il giorno 29 giu 2017, alle ore 03:18, Ben Cohen via swift-evolution 
>>> mailto:swift-evolution@swift.org>> ha scritto:
>>> 
>>> Finally, there’s a woolier justification: there’s an often-touted 
>>> misconception out there that force unwraps are bad, that they were only 
>>> created to accommodate legacy apps, and that force-unwrapping is always bad 
>>> and you should never do it. This isn’t true – there are many good reasons 
>>> to use force unwrap (though if you reaching for it constantly it’s a bad 
>>> sign). Force-unwrapping is often better than just whacking in a default 
>>> value or optional chaining when the presence of nil would indicate a 
>>> serious failure. Introduction of the `!!` operator could help 
>>> endorse/encourage the use of “thoughtful” force-unwrapping, which often 
>>> comes with a comment of the reasoning why it’s safe (of why the array can’t 
>>> be empty at this point, not just that it is empty). And if you’re going to 
>>> write a comment, why not make that comment useful for debugging at the same 
>>> time.
>>> 
>> 
>> If one could still just "!" I'm not sure that the "!!" would really 
>> encourage a more thoughtful force unwrapping. Almost every crash related to 
>> a force unwrap that I see from Swift beginners is 100% due to the fact that 
>> adding and exclamation point makes the code compile, so they add it.
>> 
>> Also, I strongly disagree with your statement that the idea that 
>> force-unwraps are bad is a misconception: if something is Optional, there's 
>> a reason why it is, otherwise it would not be Optional at all, and that's 
>> the reason why Optional exists in Swift and represents a substantial 
>> technological advancement over Objective-C. Using an Optional means that we 
>> are actually adding a thoughtful information to an instance: it could be 
>> there, or it could not, and that's perfectly fine. Crashing an app in 
>> production for a force-unwrap results in the poorest user experience ever, 
>> and it should never happen.
> 
> If forced unwraps are only used in instances where you specifically expect 
> the optional to not be nil, it is essentially sugar for a guard with 
> preconditionFailure: it is used to enforce invariants the app should never 
> break. It is very similar to a trap when accessing an out of bounds index in 
> an array. In those cases, I actually prefer it crashing than having the app 
> silently fail for the user, and you never finding out.
> 
> I try to limit my use of optional unwrapping but there are sometimes quite 
> useful. IMHO, they are not inherently bad, but can be badly used.
> 
>> I feel compelled to link another article, where Soroush Khanlou shows that 
>> sometimes the bare semantics of an Optional (that is, something is there or 
>> not) is not enough: http://khanlou.com/2017/03/that-one-optional-property/ 
>> <http://khanlou.com/2017/03/that-one-optional-property/>
>> 
>> I also disagree with the idea that the "?? fatalError()" alternative suffers 
>> from cognitive dissonance, for the following reasons:
>> 
>> - on the ri

Re: [swift-evolution] [Pitch] Introducing the "Unwrap or Die" operator to the standard library

2017-06-29 Thread Elviro Rocca via swift-evolution

> Il giorno 29 giu 2017, alle ore 03:18, Ben Cohen via swift-evolution 
>  ha scritto:
> 
> Finally, there’s a woolier justification: there’s an often-touted 
> misconception out there that force unwraps are bad, that they were only 
> created to accommodate legacy apps, and that force-unwrapping is always bad 
> and you should never do it. This isn’t true – there are many good reasons to 
> use force unwrap (though if you reaching for it constantly it’s a bad sign). 
> Force-unwrapping is often better than just whacking in a default value or 
> optional chaining when the presence of nil would indicate a serious failure. 
> Introduction of the `!!` operator could help endorse/encourage the use of 
> “thoughtful” force-unwrapping, which often comes with a comment of the 
> reasoning why it’s safe (of why the array can’t be empty at this point, not 
> just that it is empty). And if you’re going to write a comment, why not make 
> that comment useful for debugging at the same time.
> 

If one could still just "!" I'm not sure that the "!!" would really encourage a 
more thoughtful force unwrapping. Almost every crash related to a force unwrap 
that I see from Swift beginners is 100% due to the fact that adding and 
exclamation point makes the code compile, so they add it.

Also, I strongly disagree with your statement that the idea that force-unwraps 
are bad is a misconception: if something is Optional, there's a reason why it 
is, otherwise it would not be Optional at all, and that's the reason why 
Optional exists in Swift and represents a substantial technological advancement 
over Objective-C. Using an Optional means that we are actually adding a 
thoughtful information to an instance: it could be there, or it could not, and 
that's perfectly fine. Crashing an app in production for a force-unwrap results 
in the poorest user experience ever, and it should never happen.

I feel compelled to link another article, where Soroush Khanlou shows that 
sometimes the bare semantics of an Optional (that is, something is there or 
not) is not enough: http://khanlou.com/2017/03/that-one-optional-property/ 


I also disagree with the idea that the "?? fatalError()" alternative suffers 
from cognitive dissonance, for the following reasons:

- on the right of the "??" operator there could be both an Optional or a 
non-Optional, which would result in a different type for the resulting instance;
- fatalError() by itself is an operation that changes the meaning of a 
function, making it non-total, and its very name conveys a clear meaning to a 
person that reads the code, thus it really doesn't seem to me that "?? 
fatalError()" could be misinterpreted;

Anyway, it would be interesting to consider "!! message" as an alternative to 
"!", thus forcing the user to at least do extra effort: that could discourage a 
light use of !.


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


Re: [swift-evolution] [Pitch] Introducing the "Unwrap or Die" operator to the standard library

2017-06-28 Thread Elviro Rocca via swift-evolution
Yep, "logic" failures are not supposed to be there if not for avoiding checks 
that could worsen performance in pieces of code that should run as fast as 
possible. I like Adrian's solution because it doesn't add a new operator to the 
standard library, something that could mean one more encouragement to force 
unwrap things.

About preconditions, Cocoa with Love's Matt Gallagher wrote an article some 
months ago on partial functions, why you should avoid them and how to do so: 
it's a very interesting read 
http://www.cocoawithlove.com/blog/2016/01/25/partial-functions-part-one-avoidance.html
 



Elviro

> Il giorno 28 giu 2017, alle ore 07:02, Yuta Koshizawa via swift-evolution 
>  ha scritto:
> 
> ...
> 
> Logic failures are intended to be handled by fixing the code. It means
> checks of logic failures can be removed if the code is tested enough.
> Actually checks of logic failures for various operations, `!`,
> `array[i]`, `&+` and so on, are designed and implemented to be removed
> when we use `-Ounchecked`. It is useful for heavy computation like
> image processing and machine learning in which overhead of those
> checks is not permissible.
> 
> So I think checks for `!!` should be removed with `-Ounchecked` as well.
> 
> --
> Yuta
> 

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


Re: [swift-evolution] Revisiting SE-0110

2017-06-23 Thread Elviro Rocca via swift-evolution
Hi, thanks for the answer.

>> …by showing code that’s marginally different from each other, like one more 
>> nesting of parentheses, or one less label for a parameter. It seems to me 
>> that distinctions like these are just important at the compiler level, but 
>> not particularly useful from an usability standpoint.
> 
> It is your opinion that these distinctions are not “useful from a usability 
> standpoint”. My opinion, for example, differs in that I think these 
> distinctions in the structure of the types is very important, even if the 
> types “information content” is the same. Structure also conveys information 
> (and intent).
> 

What I meant by "marginally different" is a distinction like ((A,B)) != (A,B) 
which seems to me completely meaningless from a user perspective.

I'm not sure how completely isomorphic structures (represented by tuples) could 
convey different information and intent. For example:

let x: (coordinates: (Double,Double), altitude: Double) == ((A,B),C)
let y: (latitude: Double, longitude: Double, altitude: Double) ==  (A,B,C)

In this case what conveys information are the arguments labels, not the 
structure by itself. And if I really need to be specific about the information 
that I want to represent, I should probably create a new actual type, for 
example a "Position" struct, such that the example becomes:

let z: Position == (A)

That's different. What I'm referring to are just tuples in general. A function 
that expects a "Position" should get a "Position", but if a function just 
expects 3 "Double" I don't see a reason why we shouldn't be able to call it 
with both "x" and "y": of course I could do something nonsensical in this 
context, like return a sum of the 3, but here the problem is "not using types 
that are specific enough", or simply "calling the wrong function" (like 
"square" instead of "squareRoot").

>> The point is that, the following type couples are completely isomorphic to 
>> each other (meaning that they are, for all means, equivalent) and a smart 
>> type system could in theory consider them as the same thing:
>> 
>> (A) == ((A))
>> (A) == (((A)))
>> (A) == (A,())
>> (A) == ((),A,())
>> (A,B) == ((A,B))
>> (A,B) == (((A,B)))
>> (A,B) == (A,B,())
>> (A,B) == ((),A,B,())
>> (A,B) == ((),(A,B),())
> 
> To my mind, the examples should not compare equal (in fact, they shouldn’t 
> even be comparable by default because for those distinct types involved that 
> seems like a non-sensical question to me).
> 
> I might agree that a type system *could* consider these the same, but I don’t 
> think it should. For example, in the context of generic programming, the 
> structure of types (especially in degenerate cases such as e.g. empty tuples) 
> should strictly match what is expected; calling a function that expects two 
> tuples is not the same as calling that function with one tuple and so on. The 
> same goes for nesting tuples.

Could you please elaborate on this, providing some arguments for the statement 
"in the context of generic programming, the structure of types should strictly 
match what is expected"?

Thanks


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


Re: [swift-evolution] Revisiting SE-0110

2017-06-23 Thread Elviro Rocca via swift-evolution
This has been a very hard discussion to follow, even for a programmer that 
mostly just silently reads these threads to get a general understanding of 
what's going on in the community.

There's an overwhelming amount of messages that point out potential bugs and 
unexpected behavior by showing code that's marginally different from each 
other, like one more nesting of parentheses, or one less label for a parameter. 
It seems to me that distinctions like these are just important at the compiler 
level, but not particularly useful from an usability standpoint. I might be 
wrong but there's a lot of discussion about convenience gained or lost by 
switching different styles of syntax that are in fact completely isomorphic to 
each other.

I also read some comments about the fact that some functional programmers 
didn't take well SE-110, and as a fellow FP I can say that the reason in not 
really about style or convenience.

The point is that, the following type couples are completely isomorphic to each 
other (meaning that they are, for all means, equivalent) and a smart type 
system could in theory consider them as the same thing:

(A) == ((A))
(A) == (((A)))
(A) == (A,())
(A) == ((),A,())
(A,B) == ((A,B))
(A,B) == (((A,B)))
(A,B) == (A,B,())
(A,B) == ((),A,B,())
(A,B) == ((),(A,B),())

It's probably late to just casually add a couple of cents to a discussion that 
has been going for so long, but it seems to me that from a user standpoint, 
that uses types to structure their programs and define logic and relationships, 
isomorphic types should be considered the same by the compiler. The added 
burden of distinguishing between, to say, a function that takes 2 arguments and 
one that takes a single tuple of two arguments doesn't seem useful at all, at 
least from the standpoint of the types involves. All the rest, like named 
parameters or tuple labels, are just really about style and convenience, but 
isomorphic types, while not strictly equal (the very concept of "equal" is in 
fact a huge deal in abstract mathematics) are for all means "equivalent" for 
the world-modeler.

Again, I don't really expect these words to have any impact, considering the 
huge discussion that has been going, and I don't certainly intend to undermine 
any other contribution with my extremely generic statements. But I felt like 
writing this, and I did.

Thanks


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


Re: [swift-evolution] [Proposal] Higher Kinded Types (Monads, Functors, etc.)

2016-12-11 Thread Elviro Rocca via swift-evolution
Hi Chris, thanks a lot for the answer, that's exactly what I wanted to read and 
it gives me hope for the language's future :)

- Elviro

> Il giorno 12 dic 2016, alle ore 06:46, Chris Lattner  ha 
> scritto:
> 
> On Dec 11, 2016, at 5:48 AM, Elviro Rocca via swift-evolution 
> mailto:swift-evolution@swift.org>> wrote:
>> Hi everyone, I read every post in the Higher-Kinded Types ( 
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/002736.html
>>  
>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/002736.html>
>>  ) thread from about a year ago, and I was wondering what's the status on 
>> the matter: I'm aware of the proposal draft ( 
>> https://github.com/typelift/swift/issues/1 
>> <https://github.com/typelift/swift/issues/1> ), but I'd like to know if the 
>> Swift team has reconsidered the possible relevance of HKT for Swift in the 
>> foreseeable future.
> 
> Hi Elviro,
> 
> HKT’s come up from time to time, so there is definitely interest, that said, 
> I can’t imagine that this will be a priority to get done in Swift 4.
> 
>> By reading the discussion I found that the main concern from the Swift team 
>> was about practical use cases that could be of interest for a huge chunk of 
>> Swift developers: I don't think that a language feature should be there only 
>> if affects the majority of users, because of course you always have users at 
>> many different levels of awareness and understanding, not to mention 
>> experience and background,
> 
> Right.  I’m personally not opposed to having advanced features in Swift when 
> they are highly motivated.  We only aim to make sure that they only 
> affect/benefit people who want to use them.  Advanced features that beginners 
> are forced to reckon with violate our goals to have a shallow learning curve. 
>  HKTs seem like they’d be fine in this regard.
> 
>> but I understand that, considering the time constraints in language 
>> development and proposals review, the focus should (initially) be on things 
>> that matter the most to the vast majority of developers.
> 
> Right, this is the principle reason I can’t imagine that HKTs will get 
> prioritized.  There are a *TON* of improvements that will have widespread 
> positive impact, and the Swift compiler team is very thinly spread.  We are 
> forced to pick and choose a few things that we think will have the biggest 
> impact on the entire Swift community.
> 
> -Chris
> 

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


Re: [swift-evolution] [Proposal] Higher Kinded Types (Monads, Functors, etc.)

2016-12-11 Thread Elviro Rocca via swift-evolution
Hi everyone, I read every post in the Higher-Kinded Types ( 
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20151214/002736.html
 

 ) thread from about a year ago, and I was wondering what's the status on the 
matter: I'm aware of the proposal draft ( 
https://github.com/typelift/swift/issues/1 
 ), but I'd like to know if the 
Swift team has reconsidered the possible relevance of HKT for Swift in the 
foreseeable future.

By reading the discussion I found that the main concern from the Swift team was 
about practical use cases that could be of interest for a huge chunk of Swift 
developers: I don't think that a language feature should be there only if 
affects the majority of users, because of course you always have users at many 
different levels of awareness and understanding, not to mention experience and 
background, but I understand that, considering the time constraints in language 
development and proposals review, the focus should (initially) be on things 
that matter the most to the vast majority of developers.

But the idea of opposing a proposal because it's "hard to understand" (to some 
people, with different background) is baffling to me: there could be NO 
evolution whatsoever if everyone's only focus was on what feels familiar. But I 
don't want to talk about this: I just want to mention that if someone argues 
that they're not understanding a construct even if they consider themselves 
smart and experienced, that's their problem (maybe they're simply non 
experienced in that particular field), not a problem of the construct itself. 
And the fact that most things are mappable is not something functional 
programmers "believe": there's a huge corpus of research in the field of 
abstract mathematics that confirms this intuition. But anyway, let's move on.

I'd like to mention something that I consider a practical use case for the need 
of being able to express something like mappables and flatMappables in a 
abstract way: what's usually referred to as "monad transformers". I know that 
it's another concept that can be hard to grasp if you're not used to work with 
monads, but bear with me. Also, not sure about the etiquette here: it's an old 
discussion, but I wanted to offer my two cents.

Many functional programming techniques try to achieve true composability of 
code by decomposing logic in generic classes, that express a particular piece 
of that logic: the "Result" type  ( https://github.com/antitypical/Result 
 ) is a classic case (the same concept 
is similarly implemented by Swift throwable functions, but in a less composable 
way). There are many more types that do this, for example the Deferred type ( 
https://github.com/bignerdranch/Deferred 
 ) was also mentioned in the 
discussion. Another type that I use a lot is the Writer type ( 
https://en.wikipedia.org/wiki/Monad_(functional_programming)#Writer_monad 
 ) 
that lets me accumulate an auxiliary result while executing an algorithm ( for 
example, generating an index path while traversing a tree ). And the Optional 
type is already in Swift. But while these types are useful by themselves, they 
become even more powerful when combined: for example, Deferred + Result is 
basically a Future, that is, an asynchronous computation that can fail. Even 
more interesting is a Deferred + Writer + Result (I going to refer to it as 
"DefWriRes"), something that I currently use while developing my HTTP clients, 
because I can accumulate information about request and response in a clean, 
composable way: unfortunately, mapping and flatMapping breaks when combining 
these types, because mapping a DefWriRes will require a function working on 
Writer, while I really just work on the type wrapped by the internal Result. 
Monad transformers work that way: they allow you to "go deeper" in combined 
monads. Now, the interesting thing is that to map a DefWriRes we only need to 
now that Deferred, Writer and Result are mappable, but without this abstraction 
I'm forced to copy and paste hundreds of lines of code (for every possible 
combination) where the only thing that changes is the type definition, because 
the method calls are just maps.

The case is similar for flatMap, so I need to call "flatMap" on something 
that's flatMappable, with the difference that I need to be able to unwrap the 
value in the Result (so I need to know how Result works, it's not just 
mapping), and I need to be able to create a "empty" Writer and Deferred (that's 
already achievable by the type system). But the case is similar, the only 
difference is that I need a specific "ResultTransformer" (I actually 
implemented this via protocols and constrained extensions, but the 
im