Re: [swift-evolution] Re-pitch: remove(where:)

2017-09-26 Thread Robert Bennett via swift-evolution
All very good points.

> On Sep 26, 2017, at 10:32 PM, Xiaodi Wu  wrote:
> 
>> On Tue, Sep 26, 2017 at 6:48 PM, Robert Bennett  
>> wrote:
>> formFilter reads really weirdly... the use of filter in `filter` is not as a 
>> noun, but as a verb — compare to e.g., formRemainder. Calling formFilter 
>> won’t create a filter, it will “do” a filter. Perhaps formByFiltering?
> 
> That's interesting. I worry it might be too clever by half, though.
> 
> The prototypical "form" method is "formUnion"; it's so named because the term 
> "union" is used in math as both noun and verb ("a union b"; "the union of a 
> and b") and is a term of art that doesn't lend itself to the noun/verb rule 
> in Swift. Here, "filter" is a term of art (otherwise, it'd be called 
> "filtered"); now that "filter" is the non-mutating function (i.e., what 
> should otherwise be a noun), there's no way to maintain the noun/verb rule in 
> Swift. Therefore, without overthinking it, "formFilter".
> 
> Note that it's not "formUnion(with:)", just "formUnion(_:)". As is the case 
> with "formUnion", no particular attempt is made here to turn this method name 
> into an English phrase. The phrase "by filtering" very strongly suggests 
> true-to-remove; that's the only way the term "filtering" is used in English. 
> Here, we mean true-to-keep, and there's no way to express that with the 
> English word "filter" between the receiver and the predicate with any sort of 
> conjugation of the word or concise combination of helper words. The nearest 
> good-English name might be something like 
> "formFilteredResultKeeping(where:)", which is clearly awful for other reasons.
> 
>>> On Sep 26, 2017, at 7:23 PM, Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> 
 On Tue, Sep 26, 2017 at 6:14 PM, Ben Cohen via swift-evolution 
  wrote:
 And here are my answers, in a separate email to maintain a shred of 
 separation between objectivity and subjectivity :)
 
 > On Sep 26, 2017, at 4:12 PM, Ben Cohen via swift-evolution 
 >  wrote:
 >
 > 1. Is it right to assert that with a “removing” operation, the closure 
 > should return `true` for removal?
 
 Yes. If the closure returned false for removal a different, less readable, 
 name would be needed for the method.
>>> 
>>> Agree, yes.
>>> 
 > 2. Is it likely that users will want to switch from out-of- to in-place, 
 > and if so, will having to flip the closure cause confusion/bugs?
 
 I don’t think so. While the argument for an in-place remove is partly that 
 it’s more efficient than x = x.filter (in addition to 
 reability/discoverability benefits), I think that once both an in- and 
 out-of-place version are available, users will reach immediately for the 
 one they want. The scenario where you were filtering, and then you realize 
 you could do it in-place more efficiently, doesn’t seem to me like it will 
 come up in day-to-day use.
>>> 
>>> Unsure. Maybe and maybe, but I think the confusion/bugs would be limited if 
>>> the full matrix of four operations exist.
>>>  
 > 3. Should we “complete” the matrix of 4 operations, or is it fine for it 
 > to have gaps?
 
 I think filter(_:) and remove(where:) are sufficient. I don’t think we 
 need to complete the set.
>>> 
>>> Based on question (2), I would argue that the answer is yes.
>>> 
 > 4. If you are for completing, what should X and Y be called?
 >
 
 One of the reasons I _don’t_ think we should complete the set is that 
 formFilter(_:) will take us into serious jumped-the-shark territory, 
 naming-wise.
 
 I think there’s an argument for never having had filter, and always having 
 had remove/removed (or possibly select/selected), but don’t think this is 
 important enough to clear the bar for a rename of this magnitude.
>>> 
>>> IMO, they should be called removing(where:) [removed(where:) reads weirdly 
>>> in conjunction with the preceding receiver] and formFilter(_:). Hundreds of 
>>> messages finally settled on "form" as the in-place verb of choice where the 
>>> noun can't ordinarily be verbed. No point in being shy about it now: that's 
>>> the Swift way, wear it proudly.
>>> ___
>>> 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] Re-pitch: remove(where:)

2017-09-26 Thread Robert Bennett via swift-evolution
formFilter reads really weirdly... the use of filter in `filter` is not as a 
noun, but as a verb — compare to e.g., formRemainder. Calling formFilter won’t 
create a filter, it will “do” a filter. Perhaps formByFiltering?

> On Sep 26, 2017, at 7:23 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
>> On Tue, Sep 26, 2017 at 6:14 PM, Ben Cohen via swift-evolution 
>>  wrote:
>> And here are my answers, in a separate email to maintain a shred of 
>> separation between objectivity and subjectivity :)
>> 
>> > On Sep 26, 2017, at 4:12 PM, Ben Cohen via swift-evolution 
>> >  wrote:
>> >
>> > 1. Is it right to assert that with a “removing” operation, the closure 
>> > should return `true` for removal?
>> 
>> Yes. If the closure returned false for removal a different, less readable, 
>> name would be needed for the method.
> 
> Agree, yes.
> 
>> > 2. Is it likely that users will want to switch from out-of- to in-place, 
>> > and if so, will having to flip the closure cause confusion/bugs?
>> 
>> I don’t think so. While the argument for an in-place remove is partly that 
>> it’s more efficient than x = x.filter (in addition to 
>> reability/discoverability benefits), I think that once both an in- and 
>> out-of-place version are available, users will reach immediately for the one 
>> they want. The scenario where you were filtering, and then you realize you 
>> could do it in-place more efficiently, doesn’t seem to me like it will come 
>> up in day-to-day use.
> 
> Unsure. Maybe and maybe, but I think the confusion/bugs would be limited if 
> the full matrix of four operations exist.
>  
>> > 3. Should we “complete” the matrix of 4 operations, or is it fine for it 
>> > to have gaps?
>> 
>> I think filter(_:) and remove(where:) are sufficient. I don’t think we need 
>> to complete the set.
> 
> Based on question (2), I would argue that the answer is yes.
> 
>> > 4. If you are for completing, what should X and Y be called?
>> >
>> 
>> One of the reasons I _don’t_ think we should complete the set is that 
>> formFilter(_:) will take us into serious jumped-the-shark territory, 
>> naming-wise.
>> 
>> I think there’s an argument for never having had filter, and always having 
>> had remove/removed (or possibly select/selected), but don’t think this is 
>> important enough to clear the bar for a rename of this magnitude.
> 
> IMO, they should be called removing(where:) [removed(where:) reads weirdly in 
> conjunction with the preceding receiver] and formFilter(_:). Hundreds of 
> messages finally settled on "form" as the in-place verb of choice where the 
> noun can't ordinarily be verbed. No point in being shy about it now: that's 
> the Swift way, wear it proudly.
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Explicit Synthetic Behaviour

2017-09-05 Thread Robert Bennett via swift-evolution
I take issue with the fact that this problem is no different from accidentally 
gaining the default inheritance of *any* member required by a protocol and 
implemented in an extension of that protocol. The fact that in this case 
conformance is synthesized by the compiler instead of written in source code 
somewhere is immaterial; in principle, nothing is (was?) stopping the same 
default implementation from being implemented with a Mirror instead of the 
current approach.

I still think that the role keyword proposal is the best solution to this 
problem proposed so far. 
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170612/037484.html

> On Sep 5, 2017, at 4:02 PM, Haravikk via swift-evolution 
>  wrote:
> 
> Some of you will have seen my impassioned pleas on the synthesised 
> Equatable/Hashable thread against implementing implicit synthesised behaviour 
> on protocols that must, by necessity, make assumptions about a concrete type 
> that could be incorrect.
> 
> For those that haven't, the concept of synthetic behaviour in discussion here 
> is essentially any kind of default behaviour for a protocol that is 
> automatically generated based upon the concrete type itself (rather than just 
> what the protocol defines). Currently this refers to compiler magic as 
> proposed for Codable, Equatable and Hashable, but also includes the 
> reflection API and any future native macro support for Swift. Using any of 
> these to implement default methods for protocols should IMO be made explicit 
> to developers using any such protocol so that they can specifically opt-in to 
> the behaviour only if they want to and understand what it does.
> 
> This proposal idea is essentially for a new attribute @synthetic (name is up 
> for debate). This attribute is required for any default implementation that 
> includes reflective type compiler magic, use of the reflection API against 
> `self` or, in future, any native Swift macros within the method (possibly 
> limited to specific features, will depend on the macro language and its 
> capabilities). If a default method does not have this attribute, then the 
> compiler will produce an error with the appropriate fix-it. For convenience 
> this attribute can be applied to any extension block or even a protocol 
> definition in order to mark all methods in that block/type as synthetic, 
> though it's worth noting that doing so will prevent these default 
> implementations from being provided if they don't actually need this 
> attribute.
> 
> Basically the intention is that any protocol default implementation that 
> requires more knowledge about the concrete type than merely what the protocol 
> (and its parents) provide direct access to, must be marked as synthetic.
> 
> To use the synthetic behaviour of a protocol, developers must then use the 
> @synthetic keyword when conforming to it, explicitly indicating that they 
> want the extra behaviours rather than implementing the method(s) for 
> themselves. To ignore the synthetic behaviour (and thus require some kind of 
> manual implementation of methods as normal), simply omit the keyword:
> 
>   struct Foo : @synthetic Equatable { var someData:String }
>   // Type fully conforms to Equatable using synthetic behaviour 
> (equatable properties must be equal)
>   struct Foo : Equatable { var someData:String }
>   // Error due to unimplemented methods, but offers @synthetic as 
> a fix-it if all unimplemented methods are @synthetic
> 
> It is possible that the attribute could be expanded to have parameters, 
> allowing for synthetic conformance only on specific methods, but I'm unsure 
> if that'd be the best way to do it, or how likely that is to be needed.
> 
> With this kind of explicit declaration it becomes obvious within code when a 
> developer is specifically choosing to benefit from synthetic behaviour; this 
> hopefully makes it more likely that a developer will fully consider what the 
> implications of this may be, rather than doing it accidentally. The idea in 
> part is to distinguish such types as having separate protocol and synthesised 
> behaviour, where conformance without the @synthetic attribute specifically 
> requires that all protocol requirements be met in full, and that any default 
> behaviour is implemented only on the basis of the protocol itself, while 
> adding @synthetic identifies that more invasive automated behaviour is 
> permitted/requested.
> 
> At this stage I don't think there should be much of an impact for existing 
> code; as far as I can tell it should only affect any protocols that happen to 
> be using Mirror(reflecting: self) for some reason within a default 
> implementation, which I can't imagine represents a huge subsection of 
> existing code, and the fix is the simple addition of an attribute.
> 
> 
> Anyway, this is basically just a rough dump of the ideas for how the 
> synthesised Codable, 

Re: [swift-evolution] Beyond Typewriter-Styled Code in Swift, Adoption of Symbols

2017-08-31 Thread Robert Bennett via swift-evolution
Funny, of all the debates that have taken place on this list, the one that 
brings out the incivility is about editors... yet another way vim and emacs 
prove their relevance 

Seriously though, is there any reason that *all* of these suggestions can’t be 
left to the editor? Put another way: is the real desire here nicely formatted 
code in a file, or *nicely formatted code displayed on your screen*? I think 
the general opposition is to changing the language to accommodate these 
features; it doesn’t seem like anyone is opposed to the features per se. Let 
your editor display <= as the less-than-or-equal symbol (can’t type as I’m on 
mobile) and convert a typed LToE symbol to <= in the file. Let your editor 
display x.intersect(y) as x \cap y and convert x \cap y to x.intersect(y) in 
the file. Etc etc. If the mathematical matrix becomes a significant part of the 
language, I suppose #matrix((row1 entries) (row2 entries) ... (rowN entries)) 
would be fine as well. But for ease of input and display across all computers 
and editors, the underlying code should remain easy to type on a typewriter. 

My 2c.

> On Aug 31, 2017, at 7:14 PM, Dave DeLong via swift-evolution 
>  wrote:
> 
> I’m sorry, I don’t really understand the point you’re trying to make. Swift 
> is open source. Anyone is free to make a Swift editor or integrate Swift 
> support in to non-Apple IDEs, and then support additional features in their 
> IDEs to make a custom-tailored Swift experience.
> 
> I also think you forgot to turn off your caps lock.
> 
> Cheers,
> 
> Dave
> 
>> On Aug 31, 2017, at 4:33 PM, John Pratt  wrote:
>> 
>> OK BUT WHEN YOU CHANGE THE LANGUAGE YOU MIGHT ALSO CHANGE THE EDITOR.
>> WE AREN'T TO BE HELD HOSTAGE BY APPLE'S INTELLECTUAL PROPERTY OBSESSIONS
>> AND GREED.
>> 
>>> On Thu, Aug 31, 2017 at 5:17 PM, Dave DeLong  wrote:
>>> 
> On Aug 31, 2017, at 3:58 PM, David Sweeris  wrote:
> 
> 
> On Aug 31, 2017, at 2:51 PM, Dave DeLong via swift-evolution 
>  wrote:
> 
> Just a side observation…
> 
> One of the downsides I would put forward to notation like this is it 
> massively increases the barrier to entry for anyone else. I look at that 
> “Reduction.agda” file and wonder if I need to go back to school for a 
> degree in Math just to understand what’s going on.
> 
> On the other hand, while using inefficient matrix notation may be more 
> verbose, it is consistent with the other notation used in programming, 
> which means it is more easily understandable for new-comers to the code.
 
 New-comers from where? I've met more than one mathematician or physicist 
 who claims they can't code because the syntax isn't what they're used to. 
 People with different backgrounds can and do have vastly different ideas 
 about what constitutes an intuitive syntax for any given semantic (which 
 why I disagree with the notion that having more than one spelling for 
 stuff is inherently bad).
>>> 
>>> That’s a fair point, which IMO reinforces the notion that changes like this 
>>> should be an editor-level feature, and not a code-level feature.
>>> 
>>> An editor can reformat code (using a font with bazillions of ligatures or 
>>> whatever) in was that you wouldn’t want to necessarily “hard code”.
>>> 
>>> 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


Re: [swift-evolution] Beyond Typewriter-Styled Code in Swift, Adoption of Symbols

2017-08-30 Thread Robert Bennett via swift-evolution
But countless editors have popped up since vi(m) first appeared. If anything, 
this is a testament to the fact that old, “crusty” technology can remain 
relevant forever, even as new technologies offering better ergonomics enter the 
market.

Also, could someone tell me how ImageLiteral and similar types are represented 
in the file? What appears when you open it in TextEdit? This same sort of thing 
— presumably some ascii delimiters signifying specially formatted data (I don’t 
have access to a computer) — could enable the desired matrix, sqrt, etc 
functionality in Xcode. (Unless Xcode is doing preprocessing of those types 
before compiling.)

> On Aug 30, 2017, at 6:49 PM, Ryan Walklin via swift-evolution 
>  wrote:
> 
> I think we've possibly moved beyond the scope of swift-evolution. 
> Skim-reading the OP's manifesto demonstrates nothing relevant to general 
> purpose programming languages or Swift in particular.
> 
> Ryan
> 
> August 31, 2017 8:40 AM, "John Pratt via swift-evolution" 
>  wrote:
> Well, here is one question: 100 years from now do you think all computers
> should use vi?
> At what point would people ever have anything that ever slightly resembles
> something advanced?
> Do you ever want anything that
> slightly resembles science fiction, ever, in society? Or should everyone be
> using vi for the rest of civilization?
>> On Aug 30, 2017, at 5:32 PM, Eagle Offshore  wrote:
>> While I am in theory a fan of literate programming and enjoy integrated 
>> programming environments when they are integrated into a complete literate 
>> system (Smalltalk browsers, LISP environments, HyperCard, etc...)...In 
>> practice if its just a language and not a complete holistic system, and I 
>> can't command the entire thing with God's own editor (I speak of vi - 
>> because its "there" and it is the only editor guaranteed to be "there" on 
>> any system I am ever likely to try to access), I'm not gonna use it.
>> Just my $0.02
>>> On Aug 28, 2017, at 7:57 PM, John Pratt via swift-evolution 
>>>  wrote:
>>> I sent a postal envelope to the Swift team with an article I wrote, arguing 
>>> that
>>> symbols and graphics would push the programming language forward.
>>> Wouldn’t it be nice to have an actual multiplication matrix broken out into 
>>> code,
>>> instead of typing, “matrix()”? It seems to me Swift has the chance to do 
>>> that.
>>> Also: why does "<==" still reside in code as "less than or equal to” when
>>> there is a unicode equivalent that looks neat?
>>> Why can’t the square of x have a superscript of 2 instead of having 
>>> “pow(x,2)?
>>> I think this would make programming much easier to deal with.
>>> I expound on this issue in my article:
>>> http://www.noctivagous.com/nct_graphics_symbols_prglngs_draft2-3-12.pdf
>>> Thank you for reading.
>>> -John
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Beyond Typewriter-Styled Code in Swift, Adoption of Symbols

2017-08-29 Thread Robert Bennett via swift-evolution
But the question is, why does this need to affect the code base?

In the article you attached, they mention the antiquated one-line calculator 
display. The issue with that display is not the data stored in the calculator; 
it’s the display itself. An upgrade to (say) a Texas Instruments Inspire or 
whatever the newest TI calculator is (in my day we used an 83 or 84) only 
changes the display of the data; after all, you input that data will old 
fashioned buttons as well. The calculator isn’t doing any magic with the data 
itself in order to display that. If you want nicely formatted fractions, square 
roots, or matrices, go to WolframAlpha and type in your expression in ascii; 
you’ll see nicely formatted output.

Which is all to say, if you want pretty graphics in your code, all you need is 
a better front end. The backend can — and in absence of a better argument, 
should — remain unchanged.

> On Aug 29, 2017, at 3:38 PM, John Pratt via swift-evolution 
>  wrote:
> 
> The case I am making is that matrix multiplication would greatly benefit.
> 
> If by typing "matrix()" a real algebra matrix popped out of code with 
> multiple columns
> spanning multiple rows of text, wouldn't that be a major improvement for 
> everyone who
> does math or graphics?  There are a lot of these things.
> 
> Graphical elements acting as code can do much more than plain text formatting
> of any programming language's syntax.
> 
> 
> 
>> On Tue, Aug 29, 2017 at 1:38 PM, Adrian Zubarev via swift-evolution 
>>  wrote:
>> I still would prefer ligature fonts (Fira-Code). All these complicated 
>> characters might be good and so but remeber there are more than one keyboard 
>> layout on this planet, some of those are far more complicated than the 
>> English keyboard layout. Even I struggle sometimes with simple {} and [] 
>> because these characters are not visible on my German keyboard layout at all.
>> 
>> -- 
>> Adrian Zubarev
>> Sent with Airmail
>> Am 29. August 2017 um 18:27:05, Félix Cloutier via swift-evolution 
>> (swift-evolution@swift.org) schrieb:
>> 
>>> If all the hard symbols are automatically converted by the editor, why 
>>> can't the editor show you a "pretty" view and save as "regular" text? Why 
>>> does it need compiler involvement if the problem can entirely be addressed 
>>> in UI space?
>>> 
 Le 29 août 2017 à 06:14, John Pratt via swift-evolution 
  a écrit :
 
 Hi Chris: Please read the article that I originally posted and mailed to 
 the Swift team
 before shooting down what I said:
 
 http://www.noctivagous.com/nct_graphics_symbols_prglngs_draft2-3-12.pdf
 
 Alan Kay’s FONC project rewrote entire projects in far less code by
 using symbols in the Maru and Nile programming languages.  Alan Kay, as 
 you know,
 is the father of Smalltalk.  Unicode symbols can be very powerful.
 
 
 
 
 
 
> On Aug 29, 2017, at 12:28 AM, Chris Lattner  wrote:
> 
> 
>> On Aug 28, 2017, at 9:58 PM, John Pratt via swift-evolution 
>>  wrote:
>> 
>> I think the editor would recognize that "<==“ was just
>> typed and replace it with the unicode character ≤ immediately.
>> 
>> Likewise, x^2 would be recognized and turned into x with 2 in 
>> superscript.
>> 
>> As for how the UI would work for other types of symbols,
>> there are all kinds of techniques for that.  That is a UI issue,
>> for a UI design team to address.  XCode’s code completion is just one
>> example of how UI can manage input issues.
> 
> There is no reason to change the language to enable this.  Editors could 
> do this automatically.  Alternatively, you could just use a programming 
> font with ligatures for operators, see e.g.:
> https://medium.com/larsenwork-andreas-larsen/ligatures-coding-fonts-5375ab47ef8e
> https://github.com/tonsky/FiraCode
> https://www.hanselman.com/blog/MonospacedProgrammingFontsWithLigatures.aspx
> 
> -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
>> 
>> ___
>> 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

Re: [swift-evolution] (core library) modern URL types

2017-08-22 Thread Robert Bennett via swift-evolution
Since an absolute URI is still relative to root, I feel like there should be a 
way to finagle relative and absolute URIs into a single type.

> On Aug 22, 2017, at 2:37 PM, Taylor Swift via swift-evolution 
>  wrote:
> 
> So are you saying we need three distinct “URI” types for local-absolute, 
> local-relative, and remote? That’s a lot of API surface to support.
> 
>> On Tue, Aug 22, 2017 at 12:24 PM, Dave DeLong  wrote:
>> I completely agree. URL packs a lot of punch, but IMO it’s the wrong 
>> abstraction for file system paths.
>> 
>> I maintain an app that deals a lot with file system paths, and using URL has 
>> always felt cumbersome, but String is the absolute wrong type to use. Lately 
>> as I’ve been working on it, I’ve been experimenting with a concrete “Path” 
>> type, similar to PathKit (https://github.com/kylef/PathKit/). Working in 
>> terms of AbsolutePath and RelativePath (what I’ve been calling things) has 
>> been extremely refreshing, because it allows me to better articulate the 
>> kind of data I’m dealing with. URL doesn’t handle pure-relative paths very 
>> well, and it’s always a bit of a mystery how resilient I need to be about 
>> checking .isFileURL or whatever. All the extra properties (port, user, 
>> password, host) feel hugely unnecessary as well.
>> 
>> Dave
>> 
>>> On Aug 20, 2017, at 11:23 PM, Félix Cloutier via swift-evolution 
>>>  wrote:
>>> 
>>> I'm not convinced that URLs are the appropriate abstraction for a file 
>>> system path. For the record, I'm not a fan of existing Foundation methods 
>>> that create objects from an URL. There is a useful and fundamental 
>>> difference between a local path and a remote path, and conflating the two 
>>> has been a security pain point in many languages and frameworks that allow 
>>> it. Examples include remote file inclusion in PHP and malicious doctypes in 
>>> XML. Windows also had its share of issues with UNC paths.
>>> 
>>> Even when loading an arbitrary URL looks innocuous, many de-anonymizing 
>>> hacks work by causing a program to access an URL controlled by an attacker 
>>> to make it disclose the user's IP address or some other identifier.
>>> 
>>> IMO, this justifies that there should be separate types to handle local and 
>>> remote resources, so that at least developers have to be explicit about 
>>> allowing remote resources. This makes a new URL type less necessary towards 
>>> supporting file I/O.
>>> 
>>> Félix
>>> 
 Le 20 août 2017 à 21:37, Taylor Swift via swift-evolution 
  a écrit :
 
 Okay so a few days ago there was a discussion about getting pure swift 
 file system support into Foundation or another core library, and in my 
 opinion, doing this requires a total overhaul of the `URL` type (which is 
 currently little more than a wrapper for NSURL), so I’ve just started a 
 pure Swift URL library project at .
 
 The library’s parsing and validation core (~1K loc pure swift) is already 
 in place and functional; the goal is to eventually support all of the 
 Foundation URL functionality.
 
 The new `URL` type is implemented as a value type with utf8 storage backed 
 by an array buffer. The URLs are just 56 bytes long each, so they should 
 be able to fit into cache lines. (NSURL by comparison is over 128 bytes in 
 size; it’s only saved by the fact that the thing is passed as a reference 
 type.)
 
 As I said, this is still really early on and not a mature library at all 
 but everyone is invited to observe, provide feedback, or contribute!
 ___
 swift-evolution mailing list
 swift-evolution@swift.org
 https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] (core library) modern URL types

2017-08-21 Thread Robert Bennett via swift-evolution
If value-based generics become a thing, then you’ll be able to specify a URL 
type with URL<.file> which would pretty much solve this problem.

> On Aug 21, 2017, at 11:24 AM, Félix Cloutier via swift-evolution 
>  wrote:
> 
> There's no question that there's a lot in common between file: URLs and other 
> URLs, but that hardly makes URLs better in the file: case.
> 
> I saw the enum. The problem remains that it's a common API principle to 
> accept the broadest possible input. It's not fundamentally wrong to accept 
> and resolve common URL types, as there's a ton of things that need to read 
> documents from the Internet by design. However, if this is the default 
> facility for file handling too, it invents either:
> 
> A responsibility for API users to check that their URL is a file: URL;
> A responsibility for API authors to provide separate entry points for file 
> URLs and remote URLs, and a responsibility for API users to use the right one.
> 
> It would also add a category of errors to common filesystem operations: 
> "can't do this because the URL is not a file: URL", and a category of 
> questions that we arguably shouldn't need to ask ourselves. For instance, 
> what is the correct result of glob()ing a file: URL pattern with a hash or a 
> query string, should each element include that hash/query string too?
> 
> Félix
> 
>> Le 20 août 2017 à 23:33, Taylor Swift  a écrit :
>> 
>> I think that’s more a problem that lies in Foundation methods that take URLs 
>> rather than the URLs themselves. A URL is a useful abstraction because it 
>> contains a lot of common functionality between local file paths and internet 
>> resources. For example, relative URI reference resolution. APIs which take 
>> URLs as arguments should be responsible for ensuring that the URL’s schema 
>> is a `file:`. The new URL type I’m writing actually makes the scheme an enum 
>> with cases `.file`, `.http`, `.https`, `.ftp`, and `.data` to ease checking 
>> this.
>> 
>>> On Mon, Aug 21, 2017 at 2:23 AM, Félix Cloutier  
>>> wrote:
>>> I'm not convinced that URLs are the appropriate abstraction for a file 
>>> system path. For the record, I'm not a fan of existing Foundation methods 
>>> that create objects from an URL. There is a useful and fundamental 
>>> difference between a local path and a remote path, and conflating the two 
>>> has been a security pain point in many languages and frameworks that allow 
>>> it. Examples include remote file inclusion in PHP and malicious doctypes in 
>>> XML. Windows also had its share of issues with UNC paths.
>>> 
>>> Even when loading an arbitrary URL looks innocuous, many de-anonymizing 
>>> hacks work by causing a program to access an URL controlled by an attacker 
>>> to make it disclose the user's IP address or some other identifier.
>>> 
>>> IMO, this justifies that there should be separate types to handle local and 
>>> remote resources, so that at least developers have to be explicit about 
>>> allowing remote resources. This makes a new URL type less necessary towards 
>>> supporting file I/O.
>>> 
>>> Félix
>>> 
 Le 20 août 2017 à 21:37, Taylor Swift via swift-evolution 
  a écrit :
 
 Okay so a few days ago there was a discussion about getting pure swift 
 file system support into Foundation or another core library, and in my 
 opinion, doing this requires a total overhaul of the `URL` type (which is 
 currently little more than a wrapper for NSURL), so I’ve just started a 
 pure Swift URL library project at .
 
 The library’s parsing and validation core (~1K loc pure swift) is already 
 in place and functional; the goal is to eventually support all of the 
 Foundation URL functionality.
 
 The new `URL` type is implemented as a value type with utf8 storage backed 
 by an array buffer. The URLs are just 56 bytes long each, so they should 
 be able to fit into cache lines. (NSURL by comparison is over 128 bytes in 
 size; it’s only saved by the fact that the thing is passed as a reference 
 type.)
 
 As I said, this is still really early on and not a mature library at all 
 but everyone is invited to observe, provide feedback, or contribute!
 ___
 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] Fast enums (was: typed throws)

2017-08-18 Thread Robert Bennett via swift-evolution
The better solution would be to allow the creation of new enums from the union 
of existing enums, which was proposed recently.

On Aug 18, 2017, at 2:36 PM, John McCall via swift-evolution 
 wrote:

>> On Aug 18, 2017, at 6:36 AM, Jonathan Hull via swift-evolution 
>>  wrote:
>> The typed throws discussion brought me back to an old thought.
>> 
>> I would really like to see a new structural type, similar to tuples, which 
>> act as an anonymous enum.  These would actually be a distinct type from 
>> enums (not sure what to call them), in the same way that structs and tuples 
>> are different.  They would have a very similar syntax to enums though, so 
>> they would be easy to learn.
> 
> This is the commonly-rejected "Disjunctions in type constraints" feature.
> 
> John.
> 
>> 
>> There would be two major difference from enums:
>> 
>> 1) Because they are structural, they can’t have associated functions or 
>> extensions
>> 
>> 2) They can concatenate with one another freely 
>> 
>> For example:
>> 
>>func foo( speed: .slow | .med | .fast ){
>>bar(speed: speed)
>>}
>> 
>>func bar(speed: .slow | .med | .fast | .ludicrous) {
>>//but we couldn't call foo here because it doesn’t take .ludicrous
>>}
>> 
>> Each case is it’s own mini-type in a way.  One ‘.slow’ is equivalent to any 
>> ‘.slow’ (even one from a regular enum). Essentially, it is a loosely bound 
>> group of cases, and type checking just means seeing if the list/value being 
>> passed is a subset of the list of possible cases.
>> 
>> I’d also like to see sugar for quick conversion from normal Swift enums:
>> 
>>enum Speed {
>>case slow
>>case med
>>case fast
>>}
>> 
>>func foo(speed: Speed | .ludicrous) {
>>//we can’t call any functions/extensions of Speed, just like we can’t 
>> call a func from int on (Int, Int) 
>>}
>> 
>> In the above case, Speed gets converted via sugar to “.speed(Speed)” and 
>> then gets concatenated with .ludicrous. Ideally, it would have the added 
>> ability to truly convert to ".slow | .med | .fast | .ludicrous” when passed 
>> to something that doesn’t know about Speed:
>> 
>>func foo(speed: Speed | .ludicrous) {
>>switch speed {
>>case .speed(let s): //Do something with the Speed value
>>case .ludicrous: //Do something ludicrous
>>} 
>>bar(speed: speed) //This can convert to pass by unwrapping Speed to a 
>> bag of cases
>>}
>> 
>>func bar(speed: .slow | .med | .fast | .ludicrous) {
>>switch speed {
>>case .slow: //
>>case .med: //
>>case .fast: //
>>case .ludicrous: //
>>}
>>//We can’t reference Speed above because we just passed a bag of 
>> potential cases
>>}
>>
>> 
>> The end result here is that in addition to building one-off enums quickly, 
>> it lets us concatenate and extend enums for use in a limited scope.  I don’t 
>> know about you, but I run into the situation of “I want exactly this enum, 
>> but with one extra case” all the time.
>> 
>> I don’t know if we want typed throws, but this type of quick concatability 
>> would be very useful for adding/merging potential errors.  With the same 
>> sugar used on Speed above, it would also allow something similar to Union 
>> types, but without the most of the implementation headache that would cause. 
>>  You can take in multiple types, and you get back something you can switch 
>> on to recover the type which was passed:
>> 
>>func myFakeUnion(_ intOrStr: Int | String){
>>switch intOrStr {
>>case .int(let i): //Do something with int
>>case .string(let s): //Do something with string
>>}
>>} 
>> 
>>myFakeUnion(12) //Sugar!
>>myFakeUnion(.string(“Hey”)) //This works too
>> 
>> 
>> Finally, I would love to see the switch equivalent of ‘a ? b : c’ in Swift.  
>> I am not sure what the best syntax would be, but it would essentially work a 
>> bit like like a dictionary:
>> 
>>let mph = speed ? [.slow:10, .med:35, .fast:75]
>> 
>> 
>> Thanks,
>> Jon
>> 
>> 
>> 
>> 
>> ___
>> 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] Improve `init(repeating:count)`

2017-08-17 Thread Robert Bennett via swift-evolution
Xiaodi, you pretty much took the words out of my mouth. I was going to suggest 
a Count collection whose Element was Void and with the sole initializer init(_ 
count: Int). The type would just contain its count and pretty much fake its 
collection interface, in the sense that no elements are actually stored. Then 
you could do Count(3).map { UIView() }

> On Aug 17, 2017, at 9:06 PM, Erica Sadun via swift-evolution 
>  wrote:
> 
> 
>> On Aug 17, 2017, at 6:56 PM, Xiaodi Wu  wrote:
>> 
>>> On Thu, Aug 17, 2017 at 7:51 PM, Erica Sadun  wrote:
>>> What people are doing is taking a real set of values (1, 2, 3, 4, 5, for 
>>> example), then discarding them via `_ in`, which is different from `Void -> 
>>> T` or `f(x) = 0 * x`. The domain could just as easily be (Foo(), "b", ,  
>>> UIColor.red, { x: Int in x^x }). There are too many semantic shifts away 
>>> from "I would like to collect the execution of this closure n times" for it 
>>> to sit comfortably.
>> 
>> What arguments might help to alleviate this discomfort? Clearly, functions 
>> exist that can map this delightfully heterogeneous domain to some sort of 
>> range that the user wants. Would you feel better if we wrote instead the 
>> following?
>> 
>> ```
>> repeatElement((), count: 5).map { UIView() }
>> ```
> 
> My favorite solution is the array initializer. Something along the lines of 
> `Array(count n: Int, generator: () -> T)`. I'm not sure it _quite_ reaches 
> standard library but I think it is a solid way to say "produce a collection 
> with a generator run n times". It's a common  task. I was asking around about 
> this, and found that a lot of us who work with both macOS and iOS and want to 
> stress test interfaces do this very often. Other use cases include "give me n 
> random numbers", "give me n records from this database", etc. along similar 
> lines.
> 
> The difference between this and the current `Array(repeating:count:)` 
> initializer is switching the arguments and using a trailing closure  (or an 
> autoclosure) rather than a set value. That API was designed without the 
> possibility that you might want to repeat a generator, so there's a bit of 
> linguistic turbulence.
> 
> -- E
> 
 On Aug 17, 2017, at 3:53 PM, Xiaodi Wu  wrote:
 
 This is, I would argue, much too limiting in the way of semantics and not 
 at all required by “map”. It’s unclear to me how _any_ result with 
 reference semantics or any function with side effects could be used in a 
 way that comports with that definition.
 
 On the other hand, just as y = 0x is a function, { _ in Foo() } is a 
 closure that very much does project from a domain to a range. I’m not sure 
 I understand what wins are to be had by having “collect {}” as a synonym 
 for “map { _ in }”.
 
 On Thu, Aug 17, 2017 at 16:01 Erica Sadun via swift-evolution 
  wrote:
> 
>>> On Aug 17, 2017, at 12:04 PM, Max Moiseev  wrote:
>>> 
>>> 
>>> On Aug 17, 2017, at 10:05 AM, Erica Sadun via swift-evolution 
>>>  wrote:
>>> 
>>> Also, for those of you here who haven't heard my previous rant on the 
>>> subject, I dislike using map for generating values that don't depend on 
>>> transforming a domain to a range. (It has been argued that `_ in` is 
>>> mapping from `Void`, but I still dislike it immensely)
>> 
>> Can you please elaborate why (or maybe point me at the rant)? 
> 
> 
> Summary:
> 
> . Since this application is a generator and not a transformative 
> function, `map` is a misfit to usage semantics. It breaks the contract 
> that map means to project from a domain to a range via a function. More 
> languages conventionally use `collect` than `map` to collect n 
> applications of a generator closure
> 
> -- E
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>>> 
>> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-08-17 Thread Robert Bennett via swift-evolution
Alternatively, instead of replacing the current definition with an autoclosure 
version, we could leave the current version in place and add a version taking a 
function. This could be especially useful when you’ve defined a function like 
`makeMySpecialKindOfButton() -> UIButton` that does a lot of customization to 
an object before returning it.

Array(repeating: { return UIView() }, count: 3)
and
Array(repeating: makeMySpecialKindOfButton, count: 3)

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


Re: [swift-evolution] [Accepted] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-17 Thread Robert Bennett via swift-evolution
Chris mentions that the intent was to mimic a default implementation in a 
constrained protocol extension, with one extension per type that doesn’t define 
its own ==/hashValue while conforming to Equatable/Hashable. Constrained 
extensions are allowed to use type information from the constraint, so I don’t 
think there is an issue here.

> On Aug 17, 2017, at 4:12 AM, Haravikk via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> 
>> On 17 Aug 2017, at 00:06, Robert Bennett via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> How do unstable hash values play with Codable? If you encode and save a Set, 
>> might you have problems interacting with it in the future? (This is more a 
>> Codable question than Hashable, but I figure I might as well ask here) 
> 
> I'm not big on the specifics of Codable, but collections are usually a case 
> where you need to be careful about how exactly you encode them; i.e- you 
> usually only want to encode the length and the contents, not anything related 
> to the way in which they are actually stored. This way it doesn't matter if 
> the hashes change, as you recreate the Set like you're adding all the values 
> for the first time; any collisions should then be resolved as normal (i.e- 
> assigning into buckets of non-identical items with the same hash). Nothing in 
> a Set should ever be overwritten on the basis of its hash alone. Otherwise, 
> any code that requires a more stable hash value should be using something 
> other than Hashable to generate it.
> 
>> On 16 Aug 2017, at 23:29, Chris Lattner via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
> 
>> The code synthesized is meant to feel like a default implementation that 
>> you’re getting for free from a (constrained) extension on the protocol.  
>> This is why conformance to the protocol itself is all that is required, not 
>> something like “AutoEquatable”.  
> 
> 
> I still strongly feel that treating this like a default implementation is a 
> mistake, especially in the case of Equatable; we are literally talking here 
> about a feature that introduces the potential to hide bugs, and it is not the 
> same as a default implementation, not at all as it uses details of the 
> concrete type, rather than merely what is defined within the protocol itself, 
> you are talking here about using parts of a type that are not clearly 
> defined, to create an implementation that by its very nature must give 
> accurate results.
> 
> I mean, the whole point of a protocol is to define what we as developers need 
> to do in order to ensure correct behaviour; when we start talking about 
> providing that behaviour automatically with behind the scenes magic that 
> necessarily has to make assumptions about a type then you lose any ability to 
> guarantee correctness. I feel so strongly that this is a mistake that I would 
> rather never see this feature implemented than see it implemented in this 
> way, and feel that this concern has been trivialised and ignored.
> ___
> 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] [Accepted] SE-0185 - Synthesizing Equatable and Hashable conformance

2017-08-16 Thread Robert Bennett via swift-evolution
How do unstable hash values play with Codable? If you encode and save a Set, 
might you have problems interacting with it in the future? (This is more a 
Codable question than Hashable, but I figure I might as well ask here) 

> On Aug 16, 2017, at 7:02 PM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
>> On Aug 16, 2017, at 5:59 PM, Rudolf Adamkovic via swift-evolution 
>>  wrote:
>> 
>> That's great. Thanks!
> 
> Yes, excellent news!  I am *really* looking forward to seeing this proposal 
> make it into an Xcode release!
> 
>> 
>> R+
>> 
>>> On 17 Aug 2017, at 00:46, John McCall  wrote:
>>> 
 On Aug 16, 2017, at 6:35 PM, Rudolf Adamkovič via swift-evolution 
  wrote:
 
 This is fantastic news! Any chance of this landing in Swift 4.x instead of 
 5?
>>> 
>>> It it likely to be available in 4.1, but not 4.0.
>>> 
>>> John.
>>> 
 
 R+
 
> On 17 Aug 2017, at 00:29, Chris Lattner via swift-evolution 
>  wrote:
> 
> Proposal Link: 
> https://github.com/apple/swift-evolution/blob/master/proposals/0185-synthesize-equatable-hashable.md
> 
> The review of SE-0185 “Synthesizing Equatable and Hashable conformance” 
> ran from August 9…15, 2017. Feedback for the feature was glowingly 
> positive, and the proposal is accepted.  The core team discussed the 
> concerns raised in the feedback thread for the proposal.  Here are some 
> rough notes (not intended to be exhaustive), but it is important to 
> recognize that the proposal follows the design of the auto-synthesized 
> Codable proposal, and that many of these same points were discussed when 
> it came up:
> 
> - The core team feels that adding compiler magic for this case is 
> reasonable because it solves an important user need, and doesn’t preclude 
> the introduction of a more general feature (e.g. like a macro system, or 
> Rust's ‘deriving’ feature) in the future.  When/if that feature is 
> designed and built, the compiler magic can be replaced with standard 
> library magic.
> 
> - The hash value of a type is not intended to be stable across rebuilds 
> or other changes to the code.  It is ok to change if fields are 
> reordered, the standard library changes the hash function, etc.  Tony 
> pointed this out on-thread, saying:  The stdlib documentation for 
> hashValue states "Hash values are not guaranteed to be equal across 
> different executions of your program. Do not save hash values to use 
> during a future execution.”
> 
> - The code synthesized is meant to feel like a default implementation 
> that you’re getting for free from a (constrained) extension on the 
> protocol.  This is why conformance to the protocol itself is all that is 
> required, not something like “AutoEquatable”.  
> 
> Many thanks to Tony Allevato for driving forward this proposal.  The 
> patch just needs final code review now - I think we’re all looking 
> forward to this landing, congrats!
> 
> 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
>>> 
>> ___
>> 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] SE-0185 Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Robert Bennett via swift-evolution
Sorry, I think I misunderstood your earlier email. I believe we are in 
agreement.

> On Aug 10, 2017, at 5:54 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> Yes, but to be clear, this is an objection that is equally applicable to any 
> change where a protocol requirement is given a default implementation.
> 
> Unless I’m mistaken, ordinarily, the addition of such a default 
> implementation isn’t even considered an API change and doesn’t require Swift 
> Evolution approval.
>> On Thu, Aug 10, 2017 at 16:41 David Ungar <dun...@apple.com> wrote:
>> As long as I've been clear that the adoption of *this* proposal would 
>> transform a misspelling from a bug that the compiler catches to a bug that 
>> the compiler does not catch, I feel that my objection has been heard.
>> 
>> Thank you all,
>> 
>> - David
>> 
>> 
>>> On Aug 10, 2017, at 1:51 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
>>> 
>>> Right. The objection raised is applicable to the overriding of any default 
>>> implementation. However. _this_ proposal under review is about the 
>>> synthesis of a default implementation, and we shouldn’t try to invent new 
>>> syntax to address an orthogonal issue—and only partially at that.
>>> On Thu, Aug 10, 2017 at 14:45 Robert Bennett via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>>> Yes, thanks! Here’s the full proposal for those interested: 
>>>> https://github.com/erica/swift-evolution/blob/c541f517dacc2030c987b6d60ad3d26d8ec5fa3a/proposals/-role-keywords.md
>>>> 
>>>> I think that if we want to deal with the issue of some mistake arising 
>>>> from conforming to Equatable and/or Hashable, it should be through that 
>>>> proposal, not something specific to Equatable and Hashable. This sort of 
>>>> issue should not count against this Equatable/Hashable proposal.
>>>> 
>>>>>> On Aug 10, 2017, at 3:39 PM, Chris Lattner <clatt...@nondot.org> wrote:
>>>>>> 
>>>>>> 
>>>>>> On Aug 10, 2017, at 12:24 PM, Robert Bennett via swift-evolution 
>>>>>> <swift-evolution@swift.org> wrote:
>>>>>> 
>>>>>> I could have sworn that this sort of issue came up on this list earlier 
>>>>>> this year… Someone proposed a mechanism encompassing all protocols, not 
>>>>>> just Equatable and Hashable, to handle the issue of mistakenly believing 
>>>>>> you’re overriding a default implementation. Having trouble finding it at 
>>>>>> the moment.
>>>>> 
>>>>> Is this what you’re thinking of?
>>>>> https://github.com/apple/swift-evolution/pull/724
>>>>> 
>>>>> -Chris
>>>>> 
>>>>> 
>>>>> 
>>>>>> .
>>>>>> 
>>>>>>> On Aug 10, 2017, at 3:09 PM, David Ungar via swift-evolution 
>>>>>>> <swift-evolution@swift.org> wrote:
>>>>>>> 
>>>>>>> If I understand it, merely adding Equatable or Hashable will cause the 
>>>>>>> compiler to synthesize requirements. This syntax opens up the 
>>>>>>> possibility for errors:
>>>>>>> 
>>>>>>> struct Snort: Hashable {
>>>>>>> static var hashValu /* NOTE MISSPELLING */ : Int { return 666 }
>>>>>>> }
>>>>>>> 
>>>>>>> In the above example, the programmer meant to implement hashValue but 
>>>>>>> misspelled it.
>>>>>>> With the proposal as-is, the error could be covered up.
>>>>>>> 
>>>>>>> I would prefer to see a different syntax than merely adding conformance 
>>>>>>> to "HashValue", in order to distinguish the two cases: explicit 
>>>>>>> supplying the requirement vs synthesis.
>>>>>>> 
>>>>>>> Also, what if we want to extend this idea to other protocols? Perhaps 
>>>>>>> some sort of modifier on the protocol name would be more orthogonal:
>>>>>>> 
>>>>>>> struct Foo: Synth Hashable, Equatable 
>>>>>>> 
>>>>>>> Would say that Hashable requirements get synthesized but Equatable ones 
>>>>>>> do not.
>>>>>>> 
>>>>>>> Alternatively, it might be clearer, though more verbose to move the 
>>>>>>> signalling inside:
>>>>>>> 
>>>>>>> struct Snort: Hashable {
>>>>>>> synth hashValue
>>>>>>> }
>>>>>>> 
>>>>>>> (I don't advocate this specific syntax, btw.) But it has the virtual of 
>>>>>>> possibly making it clearer to read the code.
>>>>>>> 
>>>>>>> TL;DR: I favor the proposal but would prefer modification to make it 
>>>>>>> more explicit.
>>>>>>> ___
>>>>>>> swift-evolution mailing list
>>>>>>> swift-evolution@swift.org
>>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>>>> 
>>>>>> ___
>>>>>> swift-evolution mailing list
>>>>>> swift-evolution@swift.org
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>>>> 
>>>> ___
>>>> swift-evolution mailing list
>>>> swift-evolution@swift.org
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] SE-0185 Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Robert Bennett via swift-evolution
Yes, thanks! Here’s the full proposal for those interested: 
https://github.com/erica/swift-evolution/blob/c541f517dacc2030c987b6d60ad3d26d8ec5fa3a/proposals/-role-keywords.md

I think that if we want to deal with the issue of some mistake arising from 
conforming to Equatable and/or Hashable, it should be through that proposal, 
not something specific to Equatable and Hashable. This sort of issue should not 
count against this Equatable/Hashable proposal.

> On Aug 10, 2017, at 3:39 PM, Chris Lattner <clatt...@nondot.org> wrote:
> 
>> 
>> On Aug 10, 2017, at 12:24 PM, Robert Bennett via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> I could have sworn that this sort of issue came up on this list earlier this 
>> year… Someone proposed a mechanism encompassing all protocols, not just 
>> Equatable and Hashable, to handle the issue of mistakenly believing you’re 
>> overriding a default implementation. Having trouble finding it at the moment.
> 
> Is this what you’re thinking of?
> https://github.com/apple/swift-evolution/pull/724 
> <https://github.com/apple/swift-evolution/pull/724>
> 
> -Chris
> 
> 
> 
>> .
>> 
>>> On Aug 10, 2017, at 3:09 PM, David Ungar via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> If I understand it, merely adding Equatable or Hashable will cause the 
>>> compiler to synthesize requirements. This syntax opens up the possibility 
>>> for errors:
>>> 
>>> struct Snort: Hashable {
>>> static var hashValu /* NOTE MISSPELLING */ : Int { return 666 }
>>> }
>>> 
>>> In the above example, the programmer meant to implement hashValue but 
>>> misspelled it.
>>> With the proposal as-is, the error could be covered up.
>>> 
>>> I would prefer to see a different syntax than merely adding conformance to 
>>> "HashValue", in order to distinguish the two cases: explicit supplying the 
>>> requirement vs synthesis.
>>> 
>>> Also, what if we want to extend this idea to other protocols? Perhaps some 
>>> sort of modifier on the protocol name would be more orthogonal:
>>> 
>>> struct Foo: Synth Hashable, Equatable 
>>> 
>>> Would say that Hashable requirements get synthesized but Equatable ones do 
>>> not.
>>> 
>>> Alternatively, it might be clearer, though more verbose to move the 
>>> signalling inside:
>>> 
>>> struct Snort: Hashable {
>>> synth hashValue
>>> }
>>> 
>>> (I don't advocate this specific syntax, btw.) But it has the virtual of 
>>> possibly making it clearer to read the code.
>>> 
>>> TL;DR: I favor the proposal but would prefer modification to make it more 
>>> explicit.
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org <mailto:swift-evolution@swift.org>
>> https://lists.swift.org/mailman/listinfo/swift-evolution 
>> <https://lists.swift.org/mailman/listinfo/swift-evolution>
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] SE-0185 Synthesizing Equatable and Hashable conformance

2017-08-10 Thread Robert Bennett via swift-evolution
I could have sworn that this sort of issue came up on this list earlier this 
year… Someone proposed a mechanism encompassing all protocols, not just 
Equatable and Hashable, to handle the issue of mistakenly believing you’re 
overriding a default implementation. Having trouble finding it at the moment.

> On Aug 10, 2017, at 3:09 PM, David Ungar via swift-evolution 
>  wrote:
> 
> If I understand it, merely adding Equatable or Hashable will cause the 
> compiler to synthesize requirements. This syntax opens up the possibility for 
> errors:
> 
> struct Snort: Hashable {
>  static var hashValu /* NOTE MISSPELLING */ : Int { return 666 }
> }
> 
> In the above example, the programmer meant to implement hashValue but 
> misspelled it.
> With the proposal as-is, the error could be covered up.
> 
> I would prefer to see a different syntax than merely adding conformance to 
> "HashValue", in order to distinguish the two cases: explicit supplying the 
> requirement vs synthesis.
> 
> Also, what if we want to extend this idea to other protocols? Perhaps some 
> sort of modifier on the protocol name would be more orthogonal:
> 
> struct Foo: Synth Hashable, Equatable 
> 
> Would say that Hashable requirements get synthesized but Equatable ones do 
> not.
> 
> Alternatively, it might be clearer, though more verbose to move the 
> signalling inside:
> 
> struct Snort: Hashable {
>  synth hashValue
> }
> 
> (I don't advocate this specific syntax, btw.) But it has the virtual of 
> possibly making it clearer to read the code.
> 
> TL;DR: I favor the proposal but would prefer modification to make it more 
> explicit.
> ___
> 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: Regular Expression in Swift

2017-08-10 Thread Robert Bennett via swift-evolution
To me, regexes definitely feel like they belong in Foundation. Also, I don’t 
think they’d be well-served by a literal syntax (even just 
ExpressibleByStringLiteral) because this privileges using the default regex 
options over specifying non-default options. 

The compilation issue seems a bit tricky, especially if Regex is a value type. 
To avoid throwing away a cached compiled version of the Regex, you’d need to 
remember to compile it before passing it to a function. Perhaps the 
initializers could have a `precompile` argument so that you’d never forget to 
compile the regex. The Swift compiler could then optimize around that where 
possible. It should definitely be possible to create uncompiled regexes, 
though. I also agree that the compiler should warn about invalid regexes where 
possible.

> On Aug 10, 2017, at 2:30 PM, Dave DeLong via swift-evolution 
>  wrote:
> 
> 
>> On Aug 10, 2017, at 11:48 AM, Tino Heth via swift-evolution 
>>  wrote:
>> 
>> I guess everyone agrees that there should be support for regular expressions 
>> - I'm just not sure where, how and when to integrate it…
>> People seem to have a (sometimes unhealthy…) passion for regex, so I'd like 
>> to encourage a critical look on their importance.
>> For example, I don't think they belong into the stdlib — there are more 
>> basic (and much more simple) things like a Result-type or an operator for 
>> function concatenation which are not included, so why should we treat 
>> regular expressions differently?
>> But It doesn't look like we'll see a fitting library that's bundled with 
>> Swift anytime soon, and third-party regex Frameworks imho would cause big 
>> confusion.
> 
> This goes back to the idea of “non-standard libraries” that ship with Swift, 
> but aren’t imported by default. I think a “Swift.Regex” module would be 
> awesome, but I agree that it probably doesn’t need to be in the standard 
> library.
> 
> Dave
> 
>> 
>> Anyways, as you suggest a special syntax, it would be required to integrate 
>> support into Swift itself… although this is even deeper than the stdlib, I'm 
>> more positive towards that direction, as it would allow some neat tricks:
>> The expressions could not only be checked, but also translated at compile 
>> time — which could give Swift a real kickstart to beat established solutions 
>> in terms of execution speed.
>> It would, on the other hand, not work for non-literal strings, so regular 
>> expressions that are created at runtime would still need extra support…
>> 
>> If Core would consider to include compile-time regular expressions in the 
>> future, I'd support adding the new syntax, even if it's only used like 
>> NSExpression in the first implementation. Without that option, I think it's 
>> not worth it, and I'd rather try to use custom operators to build matchers 
>> that don't follow any regex standard, but are fast and safe to use.
>> ___
>> 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] [Planning][Request] "constexpr" for Swift 5

2017-08-04 Thread Robert Bennett via swift-evolution
Sorry, not sure how I missed that .

> On Aug 4, 2017, at 3:16 PM, Félix Cloutier  wrote:
> 
> 
>> Le 4 août 2017 à 11:39, Robert Bennett  a écrit :
>> 
>>> That's not a concern with the `let` case that Robert brought up, since you 
>>> can't mutate a `let` array at all.
>>> 
>>> The big thing is that unconstrained escape analysis is uncomputable. Since 
>>> Swift array storage is COW, any function that receives the array as a 
>>> parameter is allowed to take a reference on its storage. If the storage 
>>> lives on the stack and that reference outlives the stack frame, you've got 
>>> a problem. It's the same problem that motivated @escaping for closures.
>>> 
>>> You could allow storage to be on the stack by forcing user to make a 
>>> pessimistic copy, which is possibly not an improvement.
>> 
>> 
>> Good point. If this is only problematic when multiple threads are accessing 
>> an array, then it could still be worthwhile if all accesses are (provably) 
>> on the thread that created the array.
> 
> To be clear, it's a problem independently of multi-threading. `func foo() -> 
> [Int] { return [1, 2, 3] }` is the most basic representation of it: you can't 
> store the array in the stack frame if you return it. (To be fair, that one 
> would be caught by escape analysis of any quality.) `func foo() { bar([1, 2, 
> 3, 4]) }` is another example: if you don't know what `bar` does with the 
> array, you can't store it on the stack because it might pass it to an object 
> that lives on the heap and outlives `foo`, for instance. @escaping solves 
> that problem for closures by specifically annotating parameters when the 
> assigned closure could still be referenced after the called function returns.
> 
>> And pessimistic copying might still be worth it for arrays below a certain 
>> size — for instance, copying an Array of length 1 (and recall that the 
>> array in question is a constant so its size is known at compile time) would 
>> definitely be worth not having that array in heap memory.
> 
> You only need pessimistic copies when that copy escapes, and since it 
> escapes, it needs to live on the heap by definition. Right now an array of 
> size 1 passed to 4 objects on the heap has one single backing representation. 
> With pessimistic copies, you'd get 4 times that buffer of size 1, which is 
> definitely not an improvement.
> 
>> Going back to the literal notion of FSAs — fixed size arrays not necessarily 
>> on the stack — I think that simply copying Array’s implementation sans 
>> RangeReplaceableCollection conformance is not a bad way to go. Any 
>> optimizations used for `let` Arrays could probably be applied to this type 
>> of FSA.
> 
> We're actually splitting this in multiple directions. John talks of 
> variable-sized arrays necessarily on the stack. :)
> 
> I see two useful characteristics to fixed-size arrays, which, 
> uncoincidentally, are what it takes to use them for C interop:
> 
> Their storage is inlined into their container (whether it be the stack or an 
> object)
> Their length is part of their type (and not directly included with the data 
> itself)
> 
> This is also enough to implement fixed-size arrays not necessarily on the 
> stack, mind you.
> 
> Félix
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Planning][Request] "constexpr" for Swift 5

2017-08-04 Thread Robert Bennett via swift-evolution
> That's not a concern with the `let` case that Robert brought up, since you 
> can't mutate a `let` array at all.
> 
> The big thing is that unconstrained escape analysis is uncomputable. Since 
> Swift array storage is COW, any function that receives the array as a 
> parameter is allowed to take a reference on its storage. If the storage lives 
> on the stack and that reference outlives the stack frame, you've got a 
> problem. It's the same problem that motivated @escaping for closures.
> 
> You could allow storage to be on the stack by forcing user to make a 
> pessimistic copy, which is possibly not an improvement.


Good point. If this is only problematic when multiple threads are accessing an 
array, then it could still be worthwhile if all accesses are (provably) on the 
thread that created the array. And pessimistic copying might still be worth it 
for arrays below a certain size — for instance, copying an Array of length 
1 (and recall that the array in question is a constant so its size is known at 
compile time) would definitely be worth not having that array in heap memory.

Going back to the literal notion of FSAs — fixed size arrays not necessarily on 
the stack — I think that simply copying Array’s implementation sans 
RangeReplaceableCollection conformance is not a bad way to go. Any 
optimizations used for `let` Arrays could probably be applied to this type of 
FSA.

On Aug 4, 2017, at 2:15 PM, John McCall via swift-evolution 
<swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

> 
>> On Aug 4, 2017, at 1:19 PM, Félix Cloutier via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> That's not a concern with the `let` case that Robert brought up, since you 
>> can't mutate a `let` array at all.
>> 
>> The big thing is that unconstrained escape analysis is uncomputable. Since 
>> Swift array storage is COW, any function that receives the array as a 
>> parameter is allowed to take a reference on its storage. If the storage 
>> lives on the stack and that reference outlives the stack frame, you've got a 
>> problem. It's the same problem that motivated @escaping for closures.
>> 
>> You could allow storage to be on the stack by forcing user to make a 
>> pessimistic copy, which is possibly not an improvement.
> 
> Right.  I think maybe the name people keeping using for this feature is 
> misleading; a better name would be "inline arrays" or "directly-stored 
> arrays".  Having a fixed size is a necessary condition for storing the array 
> elements directly, but the people asking for this feature are really asking 
> for the different representation, not just the ability to statically 
> constrain the size of an array.
> 
> That representation difference comes with a lot of weaknesses and trade-offs, 
> but it's also useful sometimes.
> 
> John.
> 
> 
> 
>> 
>>> Le 4 août 2017 à 09:21, Taylor Swift via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :
>>> 
>>> No, that doesn’t work. In many cases you want to mutate the elements of the 
>>> array without changing its size. For example, a Camera struct which 
>>> contains a matrix buffer, and some of the matrices get updated on each 
>>> frame that the camera moves. The matrix buffer also stores all of the 
>>> camera’s stored properties, so what would be conceptually stored properties 
>>> are actually computed properties that get and set a Float at an offset into 
>>> the buffer. Of course this could all be avoided if we had fixed layout 
>>> guarantees in the language, and then the Camera struct could be the matrix 
>>> buffer and dispense with the getters and setters instead of managing a heap 
>>> buffer.
>>> 
>>> On Fri, Aug 4, 2017 at 11:02 AM, Robert Bennett via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>> So, I’m getting into this thread kind of late, and I’ve only skimmed most 
>>> of it, but…
>>> 
>>> A special FSA on the stack seems like the wrong direction. Wouldn’t it make 
>>> more sense to have *all* value types that don’t change in size — including 
>>> `let` Arrays — live on the stack? In which case, FSA would merely act like 
>>> a normal `let` Array, without RangeReplaceableCollection conformance, whose 
>>> elements could be changed via subscripting. I know nothing about the 
>>> underlying implementation details of Swift, so I may be way off base here.
>>> 
>>>> On Aug 4, 2017, at 2:18 AM, 

Re: [swift-evolution] [Planning][Request] "constexpr" for Swift 5

2017-08-03 Thread Robert Bennett via swift-evolution
Where do constant Arrays currently live? I hope the answer is on the stack, 
since their size doesn’t change.

> On Aug 3, 2017, at 8:44 PM, Taylor Swift via swift-evolution 
>  wrote:
> 
> 
> 
> On Thu, Aug 3, 2017 at 8:20 PM, Karl Wagner via swift-evolution 
>  wrote:
 
 The root cause, of course, is that the VLAs require new stack allocations 
 each time, and the stack is only deallocated as one lump when the frame 
 ends.
>>> 
>>> That is true of alloca(), but not of VLAs.  VLAs are freed when they go out 
>>> of scope.
>>> 
>> 
>> Learned something today.
>> 
>> Anyway, if the goal is stack allocation, I would prefer that we explored 
>> other ways to achieve it before jumping to a new array-type. I’m not really 
>> a fan of a future where [3; Double] is one type and (Double, Double, Double) 
>> is something else, and Array is yet another thing.
> 
> They are completely different things. 
> 
> [3; Double] is three contiguous Doubles which may or may not live on the 
> stack. 
> 
> (Double, Double, Double) is three Doubles bound to a single variable name, 
> which the compiler can rearrange for optimal performance and may or may not 
> live on the stack. 
> 
> Array is an vector of Doubles that can dynamically grow and always 
> lives in the heap.
>  
>> 
>> From what I’ve read so far, the problem with stack-allocating some Array 
>> that you can pass to another function and which otherwise does not escape, 
>> is that the function may make an escaping reference (e.g. assigning it to an 
>> ivar or global, or capturing it in a closure).
>> 
>> How about if the compiler treated every Array it receives in a function as 
>> being potentially stack-allocated. The first time you capture it, it will 
>> check and copy to the heap if necessary. All subsequent escapes (including 
>> passing to other functions) use the Array known to be allocated on the heap, 
>> avoiding further checking or copying within the function.
>> 
>> The same goes for Dictionary, and really any arbitrary value-type with COW 
>> storage. The memory that those types allocate is part of the value, so it 
>> would be cool if we could treat it like that.
>> 
> 
> This is not true. FSAs have nothing to do with automatic storage, their 
> static size only makes them eligible to live on the stack, as tuples are now. 
> The defining quality of FSAs is that they are static and contiguous. 
> ___
> 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] Inconsistencies related to prepositions

2017-08-02 Thread Robert Bennett via swift-evolution
I guess I will accept that implicit types will serve to explain the purpose of 
prepositions and do not need to be written explicitly. But I’m curious if there 
are any other thoughts on the trend exemplified by `fetch(withRecordID:)` and 
the issue that the “how” is described but not the “what”, which a more serious 
problem in my eyes, and my proposal that methods like this be of the form 
`.(:)`, where 
the second object is necessary when type information alone does not convey its 
meaning, as is the case with a record’s ID.

> On Aug 2, 2017, at 1:49 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> 
> On Wed, Aug 2, 2017 at 12:00 Robert Bennett via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> I agree with some of your points and disagree with others. You are right that 
> Swift did not get everything right when it “Swiftified” some Objective-C 
> names. However, I don’t think your criticisms are all correct.
> 
> At some point, Swift decided to omit needless “helpful” names from method 
> names. This is a good thing. You don’t “string-capitalize” a string; you 
> capitalize it. And since types are known at compile time, there isn’t really 
> a need to name the type of every argument. This would hurt the 
> readability/Englishness of Swift. For instance, `append(contentsOf:)` — in 
> English, you would say “append the contents of that bucket to my array”, not 
> “append the contents of collection that bucket to my array”. Only collections 
> can have contents so you can omit that type, both in English and in Swift. In 
> short, when the argument label clearly implies the type of the argument, 
> there’s no need to explicitly state it. However when that type is not clear 
> then it should be specified.
> 
> I think Swift did move in a weird direction with method base-names, as shown 
> in some of your examples. It relies too heavily on a shared verb among 
> methods with argument labels serving as the primary differentiators, when 
> sometimes part of the label should be attached to the verb. And for 
> arguments, it relies too heavily on type information to understand the 
> functionality; somewhat-hidden type information (inspectable in Xcode, but 
> not very obvious if you’re just reading quickly) should be made visible in 
> the argument labels where necessary.
> 
> To your specific examples:
> 
> `fetch(withRecordID)` leaves unanswered the question “what is being 
> fetched?”, instead forcing you to infer the answer from the question “how is 
> the thing being fetched, being fetched?” — “it is being fetched by record ID 
> so I guess it must be a record”. Is there even such a thing as a record ID? I 
> think not — there are just IDs, some of which are tied to records. I think 
> that that method should be called `fetchRecord(withID:)`. This makes it clear 
> that a) a record is being fetched and b) its ID is what is used to fetch it.
> `string.capitalized(with:)` it very unclear. As an uneducated programmer, I 
> have no idea what you capitalize a string “with”. With a font? With some 
> Unicode machinery? With gusto? (Ok that last one was a joke.) It’s not at all 
> obvious that you capitalize a string with a locale, and hence I think that 
> that method should be called `string.capitalized(withLocale:)`. I explain 
> above why it should be string.capitalized and not string.stringCapitalized.
> 
> This topic was reviewed extensively at the beginning of Swift Evolution. The 
> idea is that type information does not need to be repeated in the label. 
> Since the locale is of type Locale, “with” is preferred over “withLocale” 
> because “withLocale: Locale” is redundant. As this has been long approved by 
> the community, it’s not in scope to roll it back.
> 
> `dict.remove(at:)` is a bit of a tougher case. It is mutating, so it has to 
> be in the present tense. Yet it does return an element, so maybe it should 
> state that? I think the deciding vote is that it’s @discardableResult, which 
> means it should be treated as primarily removing the element; returning it is 
> secondary. Maybe to indicate the returning of the element, it should be 
> called `dict.pop(at:)`. “Pop" implies the element popped, and probably 
> implies @discardableResult in most programmers’ minds as well.
> 
> Brent had a draft proposal to revise the names of collection methods to 
> improve the situation here. There is room for improvement.
> 
> `date.timeInterval` is another tricky one. IMO the most natural choice is 
> `date.timeIntervalSince(_:)`. I don’t think the date argument label is 
> necessary because given a date, you can only compute a time interval since… 
> another date. See the `array.append(contentsOf:)` example above. And although 
> `since

Re: [swift-evolution] Inconsistencies related to prepositions

2017-08-02 Thread Robert Bennett via swift-evolution
I agree with some of your points and disagree with others. You are right that 
Swift did not get everything right when it “Swiftified” some Objective-C names. 
However, I don’t think your criticisms are all correct.

At some point, Swift decided to omit needless “helpful” names from method 
names. This is a good thing. You don’t “string-capitalize” a string; you 
capitalize it. And since types are known at compile time, there isn’t really a 
need to name the type of every argument. This would hurt the 
readability/Englishness of Swift. For instance, `append(contentsOf:)` — in 
English, you would say “append the contents of that bucket to my array”, not 
“append the contents of collection that bucket to my array”. Only collections 
can have contents so you can omit that type, both in English and in Swift. In 
short, when the argument label clearly implies the type of the argument, 
there’s no need to explicitly state it. However when that type is not clear 
then it should be specified.

I think Swift did move in a weird direction with method base-names, as shown in 
some of your examples. It relies too heavily on a shared verb among methods 
with argument labels serving as the primary differentiators, when sometimes 
part of the label should be attached to the verb. And for arguments, it relies 
too heavily on type information to understand the functionality; 
somewhat-hidden type information (inspectable in Xcode, but not very obvious if 
you’re just reading quickly) should be made visible in the argument labels 
where necessary.

To your specific examples:

`fetch(withRecordID)` leaves unanswered the question “what is being fetched?”, 
instead forcing you to infer the answer from the question “how is the thing 
being fetched, being fetched?” — “it is being fetched by record ID so I guess 
it must be a record”. Is there even such a thing as a record ID? I think not — 
there are just IDs, some of which are tied to records. I think that that method 
should be called `fetchRecord(withID:)`. This makes it clear that a) a record 
is being fetched and b) its ID is what is used to fetch it.
`string.capitalized(with:)` it very unclear. As an uneducated programmer, I 
have no idea what you capitalize a string “with”. With a font? With some 
Unicode machinery? With gusto? (Ok that last one was a joke.) It’s not at all 
obvious that you capitalize a string with a locale, and hence I think that that 
method should be called `string.capitalized(withLocale:)`. I explain above why 
it should be string.capitalized and not string.stringCapitalized.
`dict.remove(at:)` is a bit of a tougher case. It is mutating, so it has to be 
in the present tense. Yet it does return an element, so maybe it should state 
that? I think the deciding vote is that it’s @discardableResult, which means it 
should be treated as primarily removing the element; returning it is secondary. 
Maybe to indicate the returning of the element, it should be called 
`dict.pop(at:)`. “Pop" implies the element popped, and probably implies 
@discardableResult in most programmers’ minds as well.
`date.timeInterval` is another tricky one. IMO the most natural choice is 
`date.timeIntervalSince(_:)`. I don’t think the date argument label is 
necessary because given a date, you can only compute a time interval since… 
another date. See the `array.append(contentsOf:)` example above. And although 
`since` is a preposition, it should be part of the method name, and not an 
argument label, because dates do not just “have” time intervals. A database can 
fetch a record, but a date does not have a time interval — it has a time 
interval since (another date).
This should definitely be `forEach`. `array.each` would be another name for 
`array.everyElementSatisfiesCondition(_ f: (Element)->Bool))`. “For each” 
specifies that you will do something *for each* element as opposed to asking a 
question about each element. In English, “for each thing in my bucket…” will 
probably be followed by “do this thing”. You could say “for each thing in my 
bucket, it’s true that…” but you’d probably just say “everything in my bucket 
is…"

So, if I had to come up with my own rules for naming conventions:

Methods should first state what they do, then how they do it. You fetch a 
record using an ID; you don’t fetch a thing using a record ID. Ask the question 
“does the calling variable have such-and-such a thing” or “can the calling 
variable do such-and-such a thing”, and be specific about exactly what the 
thing is. If yes, than that thing is a good candidate for a method name. A 
database can fetch, sure, but more specifically it can fetch records, and 
that’s about as specific as you can get. A date doesn’t have a collection of 
time intervals sitting around, but it can compute the *time interval since* 
another date. Strings can be capitalized (with a locale), dictionaries can 
remove (at an index), arrays can append (the contents of some collection).
When the preposition/argument 

Re: [swift-evolution] [Idea] Creating an enums as a sum of multiple other enums

2017-07-31 Thread Robert Bennett via swift-evolution
That solution seems way too verbose, and also not exactly type safe because you 
must handle optionals in addition to any new cases that arise, which are 
silently handled by the default case.

To Xiaodi: is this really just value subtyping? Seems like it would also 
require multiple inheritance for it to work as suggested. To me this seems more 
like sugar for an Either type containing an arbitrary number of types (actually 
a special case of that because it’s restricted to enums).

Either way it gets a big +1 from me.

> On Jul 31, 2017, at 10:04 PM, Robert Widmann via swift-evolution 
>  wrote:
> 
> Not a response to the core of this, but to the motivating example: Sectioned 
> (or multi-sorted in other cases) ASTs can also be represented by a 
> singly-sorted AST and views over top
> 
> enum UnaryOperatorView {
>   case not
> }
> 
> enum BinaryOperatorView {
>   case and
>   case or
> }
> 
> enum BooleanLiteralView {
>   case `true`
>   case `false`
> }
> 
> enum Token {
>   case not
>   case and, or
>   case `true`, `false`
>   
>   var asUnaryOperator: UnaryOperatorView? {
> switch self {
> case .not: return .not
> default: return nil
> }
>   }
>   
>   /*etc.*/
> }
> 
> The Valence library uses this to great effect.
> 
> ~Robert Widmann
> 
>> On Jul 31, 2017, at 5:43 PM, Ahmad Alhashemi via swift-evolution 
>>  wrote:
>> 
>> I’ve been writing an interpreter in Swift and have been finding enums 
>> incredibly useful. One feature thought that I thought would make life easier 
>> is the ability to create a super-enum that contains as its cases all the 
>> cases of its constituent enums:
>> 
>>> enum UnaryOperator {
>>>case not
>>> }
>>> 
>>> enum BinaryOperator {
>>>case and
>>>case or
>>> }
>>> 
>>> case BooleanLiteral {
>>>case `true`
>>>case `false`
>>> }
>>> 
>>> typealias Token = UnaryOperator | BinaryOperator | BooleanLiteral
>> 
>> It would then be possible to do something like this:
>> 
>>> scanToken() -> Token
>>> 
>>> indirect enum Expr {
>>>case binary(op: BinaryOperator, lhs: Expr, rhs: Expr)
>>> }
>> 
>> For example, a number of functions in the recursive descent parser can only 
>> return a subset of all possible expressions.
>> 
>> Of course it’s already possible to represent the same data structure like 
>> this:
>> 
>>> enum Token {
>>>case binaryOperator(BinaryOperator)
>>>case unaryOperator(UnaryOperator)
>>>case booleanLiteral(BooleanLiteral)
>>> }
>> 
>> Perhaps what I’m suggesting could just be syntactic sugar, but it’d make it 
>> much easier to switch over `Token` without worrying about all of the nested 
>> enums. The feature becomes even more useful if you think about a deeper 
>> hierarchy of enums. It would bring some of the power of protocols/POP to 
>> enums.
>> 
>> This raises a few questions such as:
>> - Case name collisions
>> - Associated types
>> - Raw values
>> 
>> But I can’t think of anything that cannot be addressed with sensible rules 
>> and conditions.
>> 
>> Interested to read your thoughts.
>> 
>> -Ahmad
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Planning][Request] "constexpr" for Swift 5

2017-07-30 Thread Robert Bennett via swift-evolution
Is there any reason that constexpr couldn’t be inferred? Wherever you need 
something to be compile time constant — value-based generics, rawValue enum 
cases, etc — the compiler could make sure that the value was known at compile 
time, and if not then raise an error. Basically, assume everything is constexpr 
unless it can be shown to not (necessarily) be the case.

> On Jul 30, 2017, at 5:34 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
>> On Jul 30, 2017, at 10:03 AM, Gor Gyolchanyan via swift-evolution 
>>  wrote:
>> Tino Heth:
>> If you read my reply to Daniel Vollmer, you’ll find that we’re thinking 
>> about the exact same thing. Your code snippers show my vision of compiletime 
>> beautifully .
>> Now what I really want at this point is to here the opinions of the core 
>> team on this topic.
>> 
>> Swift Core Team:
>> Have you guys thought of this? Do you think this is a good idea to put on 
>> the table or do you have different plans?
> 
> I don’t speak for the core team as a whole, but here are my personal 
> opinions.  Note that this is off the cuff, without a lot of deliberate 
> consideration, so YMMV:
> 
> 1) I don’t think it makes sense to add constexpr before there is a motivating 
> use-case for it.  I agree that it could be useful with fixed sized arrays and 
> with constant parameters to generics, but we don’t have either of those yet.  
> If it were up to me, the place to start would be figuring out constant 
> generic parameters, since the answer there could inform fixed size arrays.
> 
> 2) I agree that there is heavy overlap with constexpr and macros, and that it 
> would be (probably showstoppingly) unfortunate to require duplication of 
> large swaths for the stdlib to make it work with constexprs.  Adding 
> “constexpr” to a few operator implementations would be reasonable though, and 
> may be a way to formalize “transparent”.
> 
> 3) I’m a fan of eventually adding a very general, but still hygienic, macro 
> system at some point, and assume that the # sigil will be used to for all 
> things macros.  For example, I’ve come to see the old “property behaviors” 
> proposal as being better reimagined as “property macros”, which suggest 
> syntax like “var #resettable foo : T” or something like that.
> 
> 4) The macro system should eventually support unstructured compile time 
> expansion, along the lines of what people do with Gyb and Sourcery with all 
> the tradeoffs they bring.
> 
> I tend to prefer that exploration in this space happen in order of points 
> above, and would prefer not to get to a generalized macro system for a couple 
> of years - just to give Swift more time to mature and develop without it.  
> Other languages have gotten macro systems too early in their development, and 
> become too reliant on it.  Perhaps if C didn’t have one it would have ended 
> up with a proper import mechanism.  Perhaps if Rust didn’t have one, some of 
> its decisions would have been different.  etc.
> 
> -Chris
> 
> 
> 
>> 
 On Jul 30, 2017, at 7:56 PM, Tino Heth <2...@gmx.de> wrote:
 
 
 more elaborate compile-time facilities, which would also provide extremely 
 powerful meta programming features
>>> That's an interesting twist — but whenever you put a "meta" somewhere, 
>>> things tend to get complicated, and people end up with different 
>>> associations to the topic… ;-)
>>> I took a brief look at the C++ document, but it seemed still to much 
>>> macro-like to me.
>>> 
>>> My take on the topic would be he ability to express common programming 
>>> tasks (declaring a class, overriding a method…) in the language itself.
>>> Imagine
>>> public class ProxyViewController: UIView {}
>>> Could be written as
>>> let subclass = createClass(classname: "ProxyViewController", superclass: 
>>> UIViewController, accessLevel: .public)
>>> 
>>> Quite stupid at first sight, and basically the exact opposite of syntactic 
>>> sugar ("syntactic salt" already has a meaning… so I'd call it "syntactic 
>>> pepper" ;-).
>>> But now imagine that:
>>> 
>>> for (method, implementation) in UIViewController.methods where 
>>> method.accessLevel == .open {
>>> subclass.methods[method] = { parameters in
>>> print("Subclass method \(method) called with \(parameters)")
>>> return implementation(parameters)
>>> }
>>> }
>>> 
>>> 
>>> Not that stupid anymore, isn't it?
>>> I think this would be way cooler than poking around with variants of search 
>>> & replace…
>>> 
>>> - Tino
>>> 
>>> (to get syntax colouring, I wrote ~30 lines of Swift that turn the straw 
>>> man example into valid code… it's fun, maybe I play with it a little bit 
>>> more ;-)
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> 

[swift-evolution] [Pitch] Throwing unwrap operators

2017-07-30 Thread Robert Bennett via swift-evolution
This idea was sparked by conversation in another thread about a more concise 
way to write the following:

guard let x1 = f1(), let x2 = f2(), ... else { ... }
doSomething(with: x1)
doSomething(with: x2)
...

It was suggested to write a function that throws when an optional is nil, and 
then wrapping the calls to f1, f2, ... in that function, and then wrapping 
*those* in a do-catch block. This would both exit early in case one value was 
nil, and also use the values as soon as they’re available instead of needing to 
assign them to a temp variable first and using the temp variable.

Instead of a throwing unwrap function, I am proposing a throwing unwrap 
operator. This operator would work like !, but instead of a fatal error when 
the value is nil, it would throw.

struct UnwrapError: Error {}
postfix operator ^?
extension Optional {
   static postfix func ^?(optional: Optional) throws -> Wrapped {
   guard let wrapped = optional else {
   throw UnwrapError()
   }
   return wrapped
   }
}

In addition, to round this out, I think it would be helpful to be able to throw 
arbitrary errors, as a nil value may carry meaning that should be propagated to 
the rest of the program. Thus there could be a throwing nil coalescing 
operator, which returns the unwrapped value if non-nil, or throws the specified 
error if nil.

infix operator ^??
extension Optional {
   static func ^??(lhs: Optional, rhs: Error) throws -> Wrapped {
   guard let wrapped = lhs else {
   throw rhs
   }
   return wrapped
   }
}

Thoughts? I think these would be helpful additions to allow doing something 
with Optionals while simultaneously exiting early in the case of a nil value — 
putting the unwrapping, the use, and the exiting early all on one line. 

Hopefully this doesn’t distract from the other important conversations 
happening on the mailing list!
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Change 'for in' expression to for [] { (item) in ... }

2017-07-28 Thread Robert Bennett via swift-evolution
I simply can’t see changing the syntax of such a fundamental construct, 
especially when a suitable replacement, which accomplishes your desired goal of 
introducing no new variables outside (visually) of a pair of curly braces, 
already exists. The language’s development is well past the stage of the 
cosmetics of basic syntax.

> On Jul 28, 2017, at 12:57 PM, Kwanghoon Choi  wrote:
> 
> yes, swift already has forEach, but from my point of view, there is an 
> uncomfortable part, like '(0..<10).forEach{}'. like Range type to need wrap 
> it in parentheses for using forEach.
> 
> my suggestion is not replacing 'for in [] {}' to 'for [] {}'. Can not we have 
> both? Of course, by erasing one before, it gave an environment to make 
> cleaner code easier for developers like me.
> 
> 2017-07-29 1:38 GMT+09:00 Robert Bennett :
>> Isn’t this exactly like forEach, which is already in the language?
>> 
>> > On Jul 28, 2017, at 12:32 PM, Jacob Williams via swift-evolution 
>> >  wrote:
>> >
>> > This change would also make it so that for loops follow the same format as 
>> > all other closures with variables.
>> >
>> > The downside is that this would break a TON of code. I don’t think that 
>> > the amount of code this breaks would be worth the consistency. And as Alex 
>> > mentioned, it is possible through .forEach
>> >
>> >
>> >> On Jul 28, 2017, at 10:19 AM, Kwanghoon Choi via swift-evolution 
>> >>  wrote:
>> >>
>> >> Hello
>> >>
>> >> I found someone easy mistake using for in loop statement.
>> >>
>> >> Ex)
>> >> var i = 0
>> >> for i in 0..<10 { }
>> >> print(i)
>> >>
>> >> And this user expected print(i) is “10”
>> >>
>> >> Many experienced swift developers doesn’t misunderstand like this. But 
>> >> always someone is new comers, and I think this expression make 
>> >> misunderstand easy too.
>> >>
>> >> So why not like this?
>> >>
>> >> var I = 0
>> >> for 0..<10 { (i) in … }
>> >>
>> >> I think this is more understandable for loop expression.
>> >>
>> >> Best Regards
>> >>
>> >> - Jay Choi
>> >> ___
>> >> 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] Idea: Properties in Failable Initializers less verbose

2017-07-26 Thread Robert Bennett via swift-evolution
Makes sense. Off the top of my head,  I can imagine the following two operators:

`optional?^` throws some default error if nil
`optional ??^ error` throws `error` if nil

You could have optional throwing chaining as well — basically everywhere the 
language currently offers a choice of graceful optional or potentially fatal 
force unwrap, there could be a third option to propagate an error. Is this 
worth exploring further in a new thread? I feel like this has been discussed 
and decided against...

> On Jul 26, 2017, at 4:01 PM, Chris Lattner  wrote:
> 
> 
>> On Jul 26, 2017, at 9:55 AM, Robert Bennett  wrote:
>> 
>> Is there a reason that a throwing unwrap function/operator isn’t part of the 
>> standard library? Seems like it would be handy to be able to have a 
>> one-liner for attempting to unwrap and throw if it’s nil.
> 
> ?! would be the wrong name, since ! is generally reserved for 
> potentially-trapping operations that should be avoided in most cases.
> 
> If you’re going to explore this branch of the design tree, the sensible thing 
> seems to be to (conceptually) carve off some chunk of the operator space for 
> throwing operators (e.g. ^ which could be rationalized as connoting “raising” 
> an error).  This would argue for postfix ^ to unwrap-or-throw (as an analog 
> to postfix ?, enabling chaining etc), and would then provide a schema to 
> define other “or throw” operations.
> 
> -Chris
> 
> 
> 
>> Something like
>> 
>> 
>> postfix operator .?!
>> 
>> extension Optional {
>>static postfix func .?!(optional: Optional) throws -> Wrapped {
>>switch optional {
>>case let .some(wrapped):
>>return wrapped
>>case .none:
>>throw UnwrapError()
>>}
>>}
>> }
>> 
>> init?(data: [String: Any]) {
>>do {
>>self.someProperty = try data["some_key”].?!
>>self.anotherProperty = try data["another_key”].?!
>>} catch is UnwrapError {
>>return nil
>>}
>> }
>> 
>> 
>>> On Jul 26, 2017, at 12:13 PM, Chris Lattner via swift-evolution 
>>>  wrote:
>>> 
>>> 
 On Jul 25, 2017, at 2:44 AM, philohan95 via swift-evolution 
  wrote:
 
 I think the current way to initiate models in a Failable Initializer 
 `init?()` is overly verbose and should be shortened down so less 
 boilerplate should be needed.
 
 The current way:
 
 ```
 let someProperty: Any
 let anotherProperty: Any
 
 init?(data: [String: Any]) {
guard
let someProperty = data["some_key"],
let anotherProperty = data["another_key"]
else {
return nil
}
 
self. someProperty = someProperty
self. anotherProperty = anotherProperty
 }
 ```
>>> 
>>> Guard isn’t really the right answer for this, I’d try something like this 
>>> (where unwrapOrThrow is the obvious generic function you can define 
>>> yourself):
>>> 
>>> init?(data: [String: Any]) {
>>>do {
>>>self.someProperty = try unwrapOrThrow(data["some_key”])
>>>self.anotherProperty = try unwrapOrThrow(data["another_key”])
>>>} catch {
>>>return nil
>>>}
>>> }
>>> 
>>> -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] Idea: Properties in Failable Initializers less verbose

2017-07-26 Thread Robert Bennett via swift-evolution
Is there a reason that a throwing unwrap function/operator isn’t part of the 
standard library? Seems like it would be handy to be able to have a one-liner 
for attempting to unwrap and throw if it’s nil. Something like


postfix operator .?!

extension Optional {
static postfix func .?!(optional: Optional) throws -> Wrapped {
switch optional {
case let .some(wrapped):
return wrapped
case .none:
throw UnwrapError()
}
}
}

init?(data: [String: Any]) {
do {
self.someProperty = try data["some_key”].?!
self.anotherProperty = try data["another_key”].?!
} catch is UnwrapError {
return nil
}
}


> On Jul 26, 2017, at 12:13 PM, Chris Lattner via swift-evolution 
>  wrote:
> 
> 
>> On Jul 25, 2017, at 2:44 AM, philohan95 via swift-evolution 
>>  wrote:
>> 
>> I think the current way to initiate models in a Failable Initializer 
>> `init?()` is overly verbose and should be shortened down so less boilerplate 
>> should be needed.
>> 
>> The current way:
>> 
>> ```
>> let someProperty: Any
>> let anotherProperty: Any
>> 
>> init?(data: [String: Any]) {
>>  guard
>>  let someProperty = data["some_key"],
>>  let anotherProperty = data["another_key"]
>>  else {
>>  return nil
>>  }
>> 
>>  self. someProperty = someProperty
>>  self. anotherProperty = anotherProperty
>> }
>> ```
> 
> Guard isn’t really the right answer for this, I’d try something like this 
> (where unwrapOrThrow is the obvious generic function you can define yourself):
> 
> init?(data: [String: Any]) {
>   do {
>   self.someProperty = try unwrapOrThrow(data["some_key”])
>   self.anotherProperty = try unwrapOrThrow(data["another_key”])
>   } catch {
>   return nil
>   }
> }
> 
> -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-25 Thread Robert Bennett via swift-evolution
Optional.some(Void) gives me "Expected member name or constructor call after 
type name”.

And as I said, the compiler should not be allowed to use the absence of 
parentheses to infer a Void generic type; only when the generic type is known 
to be Void may the parentheses be omitted. Under this proposal, Optional.some 
would not be allowed.

The scenario I’m working with, which inspired this thought, is roughly:

enum Result {
case success(T)
case failure(Error)
}

func doSomething(completion: @escaping (Result)->()) { /* At some point, 
call completion(.success(())) */ }

The idea is that in case of success, I merely want to indicate success, whereas 
in case of an error I want to pass the error through to the completion. This 
requires calling `completion(.success(()))`. I don’t think I should have to 
make another enum with the same cases but no associated value for success (and 
no generic type) to make this work nicely — that makes things brittle in case I 
ever want to replace Void with a different type.

> On Jul 25, 2017, at 5:20 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> Yes, I discussed this some time back. It breaks some things with overloads, 
> if I recall, but off the top of my head not recalling what.
> 
> At some point, I also suggested regarding any case without associated values 
> as equivalent to a case with an associated value of type Void. This was never 
> adopted. There _is_ an underlying issue with that idea, as the property “foo” 
> is not the same as the method “foo(_: Void)”, and it is even permitted to 
> have both of these on the same type. The purpose of the most recent Swift 
> proposal on enum cases was to align the syntax with functions as closely as 
> possible; if overloading the base name of a case (as proposed back then to 
> favorable reviews) is ever allowed, then the same will naturally be possible 
> with enums (that is, a case named “foo” and another named “foo(_: Void)” in 
> the same type).
> 
> In the case of concrete enums, a case with associated value of type Void can 
> be given a default value once they are supported (already approved); the 
> trouble here is that in the generic case presented here the same is not 
> possible. It is unclear to me whether this special rule would see broad use, 
> as it appears to come into play *only* for a generic enum. Moreover, in the 
> one scenario I can think of, it reads cryptically: “let foo = Optional.some” 
> would then be allowed (while “let bar = Optional.none” still would not). The 
> upside is that it avoids having to write four or six letters 
> (“Optional.some(Void())” is never necessary, as it’s also just 
> “Optional.some(Void)”, and that reads acceptably in my view).
> On Tue, Jul 25, 2017 at 15:26 David Sweeris via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
> On Jul 25, 2017, at 12:38, Robert Bennett via swift-evolution 
> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
> 
>> Currently if you have the following enum:
>> 
>> enum E {
>>  case c(T)
>> }
>> 
>> then if T is Void, you have to write one of the following:
>> 
>> let x: E = .c(Void())
>> let y: E = .c(())
>> 
>> Looks awkward, no? In this case you can omit `` after `E` because it 
>> can be inferred, but if writing a (non-generic) function taking an argument 
>> of type `E`, then the `` cannot be omitted, and you still have 
>> to write `.c(())` for the case name.
>> 
>> I’m proposing that for enum cases with a single associated value of Void 
>> type, or of a generic type that is equal to Void in some instance, you may 
>> omit the parentheses altogether and merely write
>> 
>> let x: E = .c
>> 
>> The rationale is twofold: first, double parentheses just looks bad; second, 
>> there is only a single value of type Void, which means the associated value 
>> of `.c` is trivially inferable, and hence should be omissible.
>> 
>> I am not proposing that a bare `E.c` imply a type of `E` — `E.c` 
>> should still be illegal in the absence of specification of the generic type 
>> — only that when the type is known to be `E`, `.c` can replace 
>> `.c(())`.
>> 
>> Thoughts?
> 
> My first response is +1
> 
> My second response is to ask just how much would it break things to expand 
> this and allow omitting the argument anywhere its type is known to be Void? 
> Maybe by implicitly providing a default value of `()` wherever there's a 
> `Void` argument? Like make `func foo(x: Void) {...}` implicitly become `func 
> foo(x: Void = ()) {...}`? I have a sneaking suspi

[swift-evolution] [Pitch] Small bit of sugar for enum case with Void associated value

2017-07-25 Thread Robert Bennett via swift-evolution
Currently if you have the following enum:

enum E {
case c(T)
}

then if T is Void, you have to write one of the following:

let x: E = .c(Void())
let y: E = .c(())

Looks awkward, no? In this case you can omit `` after `E` because it can 
be inferred, but if writing a (non-generic) function taking an argument of type 
`E`, then the `` cannot be omitted, and you still have to write 
`.c(())` for the case name.

I’m proposing that for enum cases with a single associated value of Void type, 
or of a generic type that is equal to Void in some instance, you may omit the 
parentheses altogether and merely write

let x: E = .c

The rationale is twofold: first, double parentheses just looks bad; second, 
there is only a single value of type Void, which means the associated value of 
`.c` is trivially inferable, and hence should be omissible.

I am not proposing that a bare `E.c` imply a type of `E` — `E.c` should 
still be illegal in the absence of specification of the generic type — only 
that when the type is known to be `E`, `.c` can replace `.c(())`.

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


Re: [swift-evolution] [Pitch] New Version of Array Proposal

2017-07-23 Thread Robert Bennett via swift-evolution
> Allowing partial indexing as you show it privileges one dimension over the 
> others, although they’re supposed to be co-equal and the reason a particular 
> dimension is privileged is due to an implementation detail.

Isn’t this a pretty important implementation detail? One of the reasons for 
introducing FSAs is for performance; physical memory layout is a key part of 
performance. Indexing the first k dimensions will return a contiguous block of 
memory, which is fast to read (in my simple mental model of memory, you’d only 
need a start position and a buffer length, although it’s probably more 
complicated than this in reality) and also cache-friendlier than accessing 
arbitrary indices due to the contiguity of the memory. This is an important 
optimization and programmers should be able to take advantage of it.

I wouldn’t oppose arbitrary partial indexing, but would suggest that to specify 
the indices along arbitrary dimensions require a method to indicate the 
performance cost of reading (and writing?) non-contiguous memory.

> On Jul 23, 2017, at 11:22 PM, Daryle Walker via swift-evolution 
>  wrote:
> 
> Allowing partial indexing as you show it privileges one dimension over the 
> others, although they’re supposed to be co-equal and the reason a particular 
> dimension is privileged is due to an implementation detail.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] New Version of Array Proposal

2017-07-23 Thread Robert Bennett via swift-evolution
I’ll throw my syntax suggestion into the mix: backslashed brackets for the 
braces, a colon for the separator.

let fsa: \[3: Int\] = \[3: 1, 2, 3\]

Or maybe go the string interpolation route and only backslash the first bracket.

let fsa: \[3: Int] = \[3: 1, 2, 3]

I think that looks pretty clean. For one-dimensional arrays, you could even 
omit the size and infer the type.

let fsa = \[1, 2, 3] // Of type \[3: Int]

And I agree with Taylor that the separator chosen should have no standalone use 
in the language — colon, semicolon, pound sign, etc are OK, but operators 
shouldn’t be used.

> On Jul 23, 2017, at 12:08 PM, Taylor Swift via swift-evolution 
>  wrote:
> 
> Using the multiplication operator as a separator character seems like an 
> extraordinarily bad idea.
> 
> let fsa:[2 * Int] = [2 * 5, 3] // [10, 3] ???
> 
> On Sun, Jul 23, 2017 at 11:59 AM, David Sweeris  > wrote:
> 
> 
> Sent from my iPhone
> 
> On Jul 23, 2017, at 08:45, Taylor Swift via swift-evolution 
> > wrote:
> 
>> 
>> 
>> On Sun, Jul 23, 2017 at 5:29 AM, Adrian Zubarev via swift-evolution 
>> > wrote:
>> I wanted to read the proposal, but skipped it as soon as I’ve seen the 
>> syntax. From the esthetic point of you the proposed syntax is really ugly. 
>> Again I’m not speaking against the feature in general, nor against any of 
>> the technical benefits fixed-size array will provide to us. I simply dislike 
>> the syntax, which in my opinion does not fit to Swift.
>> 
>> 
>> What about a double colon?
>> 
>> let fsa:[5, 2::Int] = [5, 2::[::0, 0]: 5, [::5, 1]: 6, default: -1]
> 
> I thought we'd mostly settled on "let fsa: [count * Type]" last time this 
> came up.
> 
> - Dave Sweeris 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] [swift-evolution-announce] Revision review: SE-104: Protocol-oriented integers

2017-07-21 Thread Robert Bennett via swift-evolution
To play devil’s advocate, what if their concern was initially unheeded, and now 
experience has revealed that their concern was in fact valid all along and more 
serious than other people realized it would be at the time it was initially 
raised – surely then it would be appropriate to re-raise the concern?

> On Jul 21, 2017, at 4:42 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> Over the last months, I started two threads to discuss revisions to SE-0104; 
> these received essentially no reply. I’m quite sure others have touched on 
> these topics too. This is a thread to formally _review_ certain changes, not 
> a thread to “talk about” revisions generally.
> 
> With respect to the specific issues raised: revisions are opportunities, as 
> was well said, to apply new insights gained from experience. They are _not_ 
> meant to reopen the floor for anyone who already voiced their opinion on the 
> original proposal simply to restate their opposition to particular changes. 
> While every_one_ should certainly be welcomed to the community, that does not 
> mean that every kind of participation should be. I don’t think we should be 
> shy about saying, “I’m sorry, this is not a helpful comment at this time and 
> place.”
> On Fri, Jul 21, 2017 at 11:47 David Hart via swift-evolution 
>  wrote:
>>> On 21 Jul 2017, at 17:11, Nevin Brackett-Rozinsky via swift-evolution 
>>>  wrote:
>>> 
>>> The updates look fine and reasonable to me.
>>> 
>>> That said, I think it is highly important that we have clarity regarding 
>>> what *is* the proper time, method, and process for raising issues with and 
>>> suggesting modifications to approved proposals. If there is one thing we 
>>> have learned recently it is that sometimes a proposed change sounds good 
>>> and gets approved (110, 25, etc.) which subsequently turns out to have 
>>> unintended detrimental consequences.
>>> 
>>> We are not infallible, and there will certainly be times in the future when 
>>> we think a change is good in theory, but then after experiencing it in 
>>> practice we recognize it has problems. When that happens—and happen it 
>>> will—we need to be able to correct our course. And it is far better to fix 
>>> such things before they are released to the wider world.
>>> 
>>> I don’t know if the issues Howard raises rise to that level. I haven’t 
>>> tested out the new integer protocols, so I am not in a position to weigh 
>>> the merits of the claim. Certainly in the abstract “signum” sounds like it 
>>> is asking for a property of the number, and not asking the number to do 
>>> something function-like, but I defer to those who use it in practice.
>>> 
>>> The point is, rather than shutting down discussion by saying “it has 
>>> already been approved” and “this is not the place for discussing that”, it 
>>> would greatly behoove the Swift Evolution process to have an established 
>>> method for recommending changes to already-approved proposals. We have this 
>>> time interval between when a proposal is accepted and when it appears in a 
>>> public release of the language, and it seems only natural to use it as a 
>>> beta-testing period.
>> 
>> I think it also important that we encourage people to participate and not 
>> drive them away. If we decide that a thread talking about revisions to a 
>> proposal is not the right place to discussion other grievances about the 
>> same proposal, perhaps a new thread is the right place.
>> 
>>> That way we can fix problems we encounter before they become permanent, and 
>>> similarly we can make minor changes which are obvious improvements we 
>>> somehow overlooked during the initial review.
>>> 
>>> Nevin
>>> 
>>> 
 On Fri, Jul 21, 2017 at 7:50 AM, Xiaodi Wu via swift-evolution 
  wrote:
 I understand you feel this way, but this thread is a formal review of 
 specific amendments to SE-0104. Those amendments are, again, the following:
 
 * Reorganizing shift operators
 * Removing the ArithmeticOverflow type in favor of using a simple Bool
 * Changing BinaryInteger's initializers that convert from floating point 
 values
 * Renaming BinaryInteger's init(extendingOrTruncating:)
 
> On Fri, Jul 21, 2017 at 02:08 Haravikk via swift-evolution 
>  wrote:
> 
>> On 21 Jul 2017, at 02:01, Xiaodi Wu via swift-evolution 
>>  wrote:
>> 
>> Hi Howard,
>> 
>> The removal of BitwiseOperations is not under review here; that, like 
>> signum(), has been considered twice and approved twice, and has not been 
>> revised.
>> 
>> On Thu, Jul 20, 2017 at 19:36 Howard Lovatt via swift-evolution 
>>  wrote:
 The revised version of the proposal can be found here:
 

Re: [swift-evolution] Enforce non-nil assignment to an implicitly unwrapped optional property?

2017-07-19 Thread Robert Bennett via swift-evolution
Another valid reason to nullify implicitly unwrapped optional would be to free 
up some memory. I don’t think we want to disallow this behavior.

If you really need to be unable to assign nil to an implicitly unwrapped 
optional, you can fake it using this code. S.value acts like an implicitly 
unwrapped optional, except that the compiler won’t let you assign an optional 
to it.


struct S {
struct T {
var value: Int
}

private var t: T?
var value: Int {
get { return self.t!.value }
set { 
if self.t == nil {
self.t = T(value: newValue)
} else {
self.t!.value = newValue
}
}
}
}


> On Jul 19, 2017, at 8:07 AM, Rod Brown via swift-evolution 
>  wrote:
> 
> Implicitly unwrapped optionals are often used when the optional system is a 
> little complicated around one of your variables.
> 
> Some of those times are variables that are nil-resettable (where you set nil, 
> and it internally does something to use that as a reset case) or 
> initialisation issues where you can’t know a variable at prior to the 
> initialisation, but can get it out. But these are just two examples.
> 
> I think trying to work more on tying people’s hands with this attribute 
> specifically designed to handle edge cases seems a little… concerning.
> 
> It might make more sense to use a computed property covering the internal 
> property completely if you need this behaviour? 
> 
>> On 19 Jul 2017, at 3:31 pm, Glen Huang via swift-evolution 
>>  wrote:
>> 
>> Anyone has any thoughts on this?
>> 
>>> On 16 Jul 2017, at 3:46 PM, Glen Huang via swift-evolution 
>>>  wrote:
>>> 
>>> I want to define a property for a struct/class that is nil after 
>>> initialization, but later is guaranteed to have a value after I manually 
>>> assign to it. I think implicitly unwrapped optional property is designed 
>>> specifically for that.
>>> 
>>> However, the problem arises when it comes to how do I enforce that I never 
>>> mistakenly assign nil to this property?
>>> 
>>> struct Foo {
>>>  var name: String!
>>> }
>>> var foo = Foo()
>>> 
>>> I can do foo.name = nil and it will compile just fine.
>>> 
>>> I guess I could do a run-time check with something like:
>>> 
>>> struct Foo {
>>>  var name: String! {
>>>  willSet {
>>>  if newValue == nil {
>>>  fatalError("nil isn't allowed")
>>>  }
>>>  }
>>>  }
>>> }
>>> 
>>> But it feels ugly, and seems to be something checkable at compile time.
>>> 
>>> I could define a new setter method:
>>> 
>>> struct Foo {
>>>  private(set) var name: String!
>>>  mutating func setName(_ name: String) {
>>>  self.name = name
>>>  }
>>> }
>>> 
>>> But it feel tedious. Enforcing non-nil assignment probably fits 90% of the 
>>> use cases of IUOs, since that’s basically their definition. Having to 
>>> deviate from direct assignment syntax in usage and also define a new setter 
>>> method for the majority cases seems unfortunate.
>>> 
>>> I wonder if it’s desirable to define an attribute or something to ask the 
>>> compiler to only allow non-optionals to be assigned to IUO properties?
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Change default compiler fix for not-unwrapped Optional from ! To ?

2017-07-18 Thread Robert Bennett via swift-evolution
Another example of the compiler being not so helpful:

func f(completion: (()->())? = nil) {
completion()
}

The compiler offers to insert a ! after `completion`, which is a strictly worse 
choice than inserting a ?.

> On Jul 15, 2017, at 7:48 AM, Rod Brown <rodney.bro...@icloud.com> wrote:
> 
>> 
>> On 15 Jul 2017, at 9:54 am, Robert Bennett via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>> For expressions whose type is definitely non-optional, it makes sense to 
>> verbally suggest both ! and ?? (and/or !! – was that accepted?), and it’s 
>> probably best to insert ! when the fixit is accepted. For expressions whose 
>> type is undetermined, but which need some form of Optional handling, it 
>> would be best for the compiler to assume the type is meant to be optional 
>> and insert a ?.
> 
> I think its fair that where the context can be optional, the default fixit 
> should be optional. I’ve seen this issue myself from junior swift devs where 
> they apply a fixit.
> 
> e.g.:
> 
> let optionalReturnedValue = item.optionalValue.optionalValue2?.item
> 
> And the fixit Xcode recommends on optionalValue is “!"…
> 
> let optionalReturnedValue = item.optionalValue!.optionalValue2?.item
> 
> It seems wiser in these cases if the compiler is smart enough for the default 
> fixit to be “?”. I’m not sure if the compiler is able to do that or is in 
> scope, that’s for smarter people than I to say.
> 
> In cases where the compiler, due to the context, requires the value to be 
> non-optional, for a “!”, “??”, or the proposed “!!” makes sense.
> 
> “If let”, “guard let” etc all very much butcher the code at the callsite. 
> They fundamentally change the control flow, and I could imagine many of the 
> times its suggestions really won’t make sense for the given situation. How 
> smart should we make the compiler before we’re practically making it rewrite 
> all your code anyway? In this case, I’d rather there be no fixit at all, and 
> just let the developer actually understand and restructure their code to 
> correctly handle the optional case.
> 
> - Rod
> 
> 
>> 
>> On Jul 14, 2017, at 2:41 PM, Erica Sadun via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> 
>>> 
>>>> On Jul 14, 2017, at 2:11 AM, Víctor Pimentel via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>>> On 14 Jul 2017, at 08:05, Rod Brown via swift-evolution 
>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>> 
>>>>> 
>>>>> 
>>>>>> On 14 Jul 2017, at 2:36 pm, Robert Bennett via swift-evolution 
>>>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>>>> 
>>>>>> When writing Swift code, it is not uncommon to forget to unwrap 
>>>>>> optionals. The compiler will offer a fixit, telling you you must insert 
>>>>>> either a ? or a !. However, when you accept the fixit, ! is inserted (at 
>>>>>> least, it is for me in Xcode 8.3).
>>>>> When you treat an optional as non-optional, the compiler has no way to do 
>>>>> a fixit that would appropriately handle the optional. Felix made a good 
>>>>> example. The only direct fixit would be a force unwrap. If you used “?” 
>>>>> then your non-optional use would turn into an optional and your parameter 
>>>>> would generally be non-optional. The fixit is just explicitly doing what 
>>>>> you implicitly expected it to do.
>>>>> 
>>>>>> 
>>>>>> Ideally the fixit would default to ? because this is the preferred 
>>>>>> option; ! is often a sign of non-Swifty code and does not interact well 
>>>>>> with idiomatic Swift constructs such as if-let-(as?), 
>>>>>> guard-let-(as?)-else, etc. Also I think it’s safe to say that fixits 
>>>>>> should not err on the side of crashing at runtime.
>>>>> 
>>>>> " ! is often a sign of non-Swifty code “
>>>>> I would strongly challenge this assumption. Many core team members have 
>>>>> commented about appropriate uses of the ! operator. It shouldn’t be used 
>>>>> lightly, but it’s there for a reason and it most definitely isn’t 
>>>>> “non-swifty”.
>>>> 
>>>

Re: [swift-evolution] Change default compiler fix for not-unwrapped Optional from ! To ?

2017-07-14 Thread Robert Bennett via swift-evolution
For expressions whose type is definitely non-optional, it makes sense to 
verbally suggest both ! and ?? (and/or !! – was that accepted?), and it’s 
probably best to insert ! when the fixit is accepted. For expressions whose 
type is undetermined, but which need some form of Optional handling, it would 
be best for the compiler to assume the type is meant to be optional and insert 
a ?.

> On Jul 14, 2017, at 2:41 PM, Erica Sadun via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> 
>>> On Jul 14, 2017, at 2:11 AM, Víctor Pimentel via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> On 14 Jul 2017, at 08:05, Rod Brown via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> 
>>> 
>>>> On 14 Jul 2017, at 2:36 pm, Robert Bennett via swift-evolution 
>>>> <swift-evolution@swift.org> wrote:
>>>> 
>>>> When writing Swift code, it is not uncommon to forget to unwrap optionals. 
>>>> The compiler will offer a fixit, telling you you must insert either a ? or 
>>>> a !. However, when you accept the fixit, ! is inserted (at least, it is 
>>>> for me in Xcode 8.3).
>>> When you treat an optional as non-optional, the compiler has no way to do a 
>>> fixit that would appropriately handle the optional. Felix made a good 
>>> example. The only direct fixit would be a force unwrap. If you used “?” 
>>> then your non-optional use would turn into an optional and your parameter 
>>> would generally be non-optional. The fixit is just explicitly doing what 
>>> you implicitly expected it to do.
>>> 
>>>> 
>>>> Ideally the fixit would default to ? because this is the preferred option; 
>>>> ! is often a sign of non-Swifty code and does not interact well with 
>>>> idiomatic Swift constructs such as if-let-(as?), guard-let-(as?)-else, 
>>>> etc. Also I think it’s safe to say that fixits should not err on the side 
>>>> of crashing at runtime.
>>> 
>>> " ! is often a sign of non-Swifty code “
>>> I would strongly challenge this assumption. Many core team members have 
>>> commented about appropriate uses of the ! operator. It shouldn’t be used 
>>> lightly, but it’s there for a reason and it most definitely isn’t 
>>> “non-swifty”.
>> 
>> I think it's not a farfetched assumption to imply that if the compiler 
>> encounters that code, the programmer didn't realize or remember that they 
>> were dealing with optionals.
>> 
>> If the compiler suggests to force unwrap that expression, it is also fair to 
>> assume that most inexperience programmers will just apply that fix it. A 
>> more experience programmer can decide whether to force unwrap it or to 
>> handle the nil case in any other way, depending on the context and code 
>> style.
>> 
>> Personally, I'd prefer that the compiler didn't encourage so much to use 
>> force unwrapping, not because I think that it has no use, but because I 
>> think that newbies should not learn that pattern first.
>> 
>> Surely, if I were new to the language and the compiler kept doing that fix 
>> it, I would think that it's "the way" to deal with optionals.
>> 
>> What would I prefer? At least, for the fix it to provide several options, 
>> more or less in this order:
>> 
>> - checked unwrap (if applies)
>> - if let
>> - guard let
>> - force unwrap
> 
> Unfortunately, I think `!` *is* the proper fix-it here. The mechanisms to 
> insert conditional binding, for example, are too unwieldy a tool at the many 
> arbitrary places where an optional is used in place of a non-optional. I 
> believe introducing an unwrap-or-die operator in parens (see 
> https://github.com/apple/swift-evolution/pull/729) would provide a better 
> fixit:
> 
> * A sophisticated developer is unlikely to use fix-its as a blunt instrument 
> to make code work. Their use of  `!` can be appropriate and, in their hands, 
> unlikely to be fixit-driven.
> 
> * The unsophisticated developer is better served with `!!`, which 
> self-documents the safety issue and can be further evaluated for refactoring, 
> supporting safer learner patterns. Unlike the other approaches for 
> conditional binding, `!!` is fix-it friendly. 
> 
> -- E
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Change default compiler fix for not-unwrapped Optional from ! To ?

2017-07-13 Thread Robert Bennett via swift-evolution
When writing Swift code, it is not uncommon to forget to unwrap optionals. The 
compiler will offer a fixit, telling you you must insert either a ? or a !. 
However, when you accept the fixit, ! is inserted (at least, it is for me in 
Xcode 8.3).

Ideally the fixit would default to ? because this is the preferred option; ! is 
often a sign of non-Swifty code and does not interact well with idiomatic Swift 
constructs such as if-let-(as?), guard-let-(as?)-else, etc. Also I think it’s 
safe to say that fixits should not err on the side of crashing at runtime.
___
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 Robert Bennett via swift-evolution
Just realized that even inout functions don’t let you do member(object) = 
value. So you’re right, the write access does make keypaths more like 
subscripts. But when restricted to read-only access, they are identical to 
(non-inout) functions and so it does seem natural to be able to use them as 
such for the purpose of map and similar functions.

You’ve convinced me that the sigil method is probably preferable... Since write 
access does make keypaths more like subscripts, the proper way to convert 
keypaths to functions is probably an explicit piece of punctuation.

> On Jul 11, 2017, at 9:23 PM, Robert Bennett via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> Sure, but you could just as easily call a keypath “a thing that gives you 
> read+write access to one of an object’s members”. Sounds like an inout 
> function to me. The difference being that in general an inout function *can* 
> do a lot more than just give access to a single member of a base object. But 
> a keypath is still just a (constrained) inout function.
> 
>> On Jul 11, 2017, at 9:14 PM, Dave Abrahams via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> 
>>> on Tue Jul 11 2017, Robert Bennett <swift-evolution@swift.org> wrote:
>>> 
>>> Er, yes, I now realize I diverged into two different keypaths-as-functions 
>>> ideas there.
>>> 
>>> I think that the best implementation of deferred access is keypaths as
>>> callable first-class objects, like you (Karl) said. — although I
>>> wonder whether callability should be restricted to KeyPath, or
>>> instead, if the notion of a callable type should gain first-class
>>> language support.
>>> 
>>> If not possible, then a conversion sigil to make a KeyPath into a function. 
>>> After that, giving
>>> KeyPath a function `apply` is probably next best.
>>> 
>>> I like the subscript idea the least because: I don’t like the look of
>>> the syntax, keypaths feel more function-y than subscript-y, 
>>> and it diminishes the flexibility of keypaths (as this thread has
>>> revealed).
>> 
>> Because they're parameterized by a base object and a key, and (in
>> general) they're writable, they're semantically very much like
>> subscripts.
>> 
>>>> On Jul 11, 2017, at 7:56 PM, Karl Wagner <razie...@gmail.com> wrote:
>>>> 
>>>> 
>>>>> On 12. Jul 2017, at 01:20, Robert Bennett
>>>>> <rltbenn...@icloud.com
>>>>> <mailto:rltbenn...@icloud.com>> wrote:
>>>>> 
>>>>> Well, if they really are first-class deferred method calls or
>>>>> member accesses, then do seem pretty function-y after all. Then
>>>>> again, if they were meant to be functions, it seems like their
>>>>> design would reflect that – instead of being used like subscripts,
>>>>> they would be called like functions, and since new syntax had to be
>>>>> created either way, the fact that they *weren't* just made into
>>>>> callable objects seems to indicate that that was not the intent,
>>>>> although I’d have to go back and read the discussion to see exactly
>>>>> what was discussed.
>>>> 
>>>> I agree, and I suspect I’m not alone in disliking the subscript syntax.
>>>> 
>>>>> 
>>>>> That said, I agree with Benjamin that having an `apply` method for
>>>>> KeyPath seems like the right way to make (or have made) keypaths
>>>>> work. keypath.apply(to: instance) (or keypath.evaluate(on:), or
>>>>> some other name that gets the idea across) reads just as nice as
>>>>> instance[keyPath: keypath] and has the added benefit of allowing
>>>>> collection.map(keypath.apply) at no cost. But it’s probably too
>>>>> late to even bother having a discussion about this, right?
>>>> 
>>>> I don’t think so. That’s why we have a beta. Real-world experience
>>>> has shown that we would often like to erase a KeyPath and use it as
>>>> if it were a closure. Maybe we want to pass a KeyPath as a parameter
>>>> to a function such as “map", which accepts a closure, or we want to
>>>> set a variable with a closure-type using a KeyPath. Those functions
>>>> and stored properties don’t care about the special properties of
>>>> KeyPaths (e.g. that they are Codable) - they only care that they are
>>>> executable on a base object to produce a result. You can wrap the
>>>

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

2017-07-11 Thread Robert Bennett via swift-evolution
Sure, but you could just as easily call a keypath “a thing that gives you 
read+write access to one of an object’s members”. Sounds like an inout function 
to me. The difference being that in general an inout function *can* do a lot 
more than just give access to a single member of a base object. But a keypath 
is still just a (constrained) inout function.

> On Jul 11, 2017, at 9:14 PM, Dave Abrahams via swift-evolution 
> <swift-evolution@swift.org> wrote:
> 
> 
>> on Tue Jul 11 2017, Robert Bennett <swift-evolution@swift.org> wrote:
>> 
>> Er, yes, I now realize I diverged into two different keypaths-as-functions 
>> ideas there.
>> 
>> I think that the best implementation of deferred access is keypaths as
>> callable first-class objects, like you (Karl) said. — although I
>> wonder whether callability should be restricted to KeyPath, or
>> instead, if the notion of a callable type should gain first-class
>> language support.
>> 
>> If not possible, then a conversion sigil to make a KeyPath into a function. 
>> After that, giving
>> KeyPath a function `apply` is probably next best.
>> 
>> I like the subscript idea the least because: I don’t like the look of
>> the syntax, keypaths feel more function-y than subscript-y, 
>> and it diminishes the flexibility of keypaths (as this thread has
>> revealed).
> 
> Because they're parameterized by a base object and a key, and (in
> general) they're writable, they're semantically very much like
> subscripts.
> 
>>> On Jul 11, 2017, at 7:56 PM, Karl Wagner <razie...@gmail.com> wrote:
>>> 
>>> 
>>>> On 12. Jul 2017, at 01:20, Robert Bennett
>>>> <rltbenn...@icloud.com
>>>> <mailto:rltbenn...@icloud.com>> wrote:
>>>> 
>>>> Well, if they really are first-class deferred method calls or
>>>> member accesses, then do seem pretty function-y after all. Then
>>>> again, if they were meant to be functions, it seems like their
>>>> design would reflect that – instead of being used like subscripts,
>>>> they would be called like functions, and since new syntax had to be
>>>> created either way, the fact that they *weren't* just made into
>>>> callable objects seems to indicate that that was not the intent,
>>>> although I’d have to go back and read the discussion to see exactly
>>>> what was discussed.
>>> 
>>> I agree, and I suspect I’m not alone in disliking the subscript syntax.
>>> 
>>>> 
>>>> That said, I agree with Benjamin that having an `apply` method for
>>>> KeyPath seems like the right way to make (or have made) keypaths
>>>> work. keypath.apply(to: instance) (or keypath.evaluate(on:), or
>>>> some other name that gets the idea across) reads just as nice as
>>>> instance[keyPath: keypath] and has the added benefit of allowing
>>>> collection.map(keypath.apply) at no cost. But it’s probably too
>>>> late to even bother having a discussion about this, right?
>>> 
>>> I don’t think so. That’s why we have a beta. Real-world experience
>>> has shown that we would often like to erase a KeyPath and use it as
>>> if it were a closure. Maybe we want to pass a KeyPath as a parameter
>>> to a function such as “map", which accepts a closure, or we want to
>>> set a variable with a closure-type using a KeyPath. Those functions
>>> and stored properties don’t care about the special properties of
>>> KeyPaths (e.g. that they are Codable) - they only care that they are
>>> executable on a base object to produce a result. You can wrap the
>>> key-paths inside closures, but it’s cumbersome and some developers
>>> are asking for a shorthand to perform that erasure.
>>> 
>>> Personally, I would be in favour of making the erasure implicit and 
>>> allowing KeyPaths to be invoked using function-syntax:
>>> 
>>> // Invocation using function-syntax:
>>> 
>>> let _: Value = someClosure(parameter)
>>> let _: Value = someKeypath(parameter)
>>> 
>>> let _: Value = { $0.something.anotherThing }(parameter)
>>> let _: Value = (\MyObj.something.anotherThing)(parameter)
>>> 
>>> // Implicit erasure to closure-type:
>>> 
>>> class PrettyTableCell {
>>>let titleFormatter: (T) -> String
>>> }
>>> let cell= PrettyTableCell()
>>> cell.titleFormatter = \MyObj.something.name
>>> 
>>> let stuff = myObjects.map(\.something

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

2017-07-11 Thread Robert Bennett via swift-evolution
Er, yes, I now realize I diverged into two different keypaths-as-functions 
ideas there.

I think that the best implementation of deferred access is keypaths as callable 
first-class objects, like you (Karl) said. — although I wonder whether 
callability should be restricted to KeyPath, or instead, if the notion of a 
callable type should gain first-class language support.

If not possible, then a conversion sigil to make a KeyPath into a function. 
After that, giving KeyPath a function `apply` is probably next best.

I like the subscript idea the least because: I don’t like the look of the 
syntax, keypaths feel more function-y than subscript-y, and it diminishes the 
flexibility of keypaths (as this thread has revealed).

> On Jul 11, 2017, at 7:56 PM, Karl Wagner <razie...@gmail.com> wrote:
> 
> 
>> On 12. Jul 2017, at 01:20, Robert Bennett <rltbenn...@icloud.com 
>> <mailto:rltbenn...@icloud.com>> wrote:
>> 
>> Well, if they really are first-class deferred method calls or member 
>> accesses, then do seem pretty function-y after all. Then again, if they were 
>> meant to be functions, it seems like their design would reflect that – 
>> instead of being used like subscripts, they would be called like functions, 
>> and since new syntax had to be created either way, the fact that they 
>> *weren't* just made into callable objects seems to indicate that that was 
>> not the intent, although I’d have to go back and read the discussion to see 
>> exactly what was discussed. 
> 
> I agree, and I suspect I’m not alone in disliking the subscript syntax.
> 
>> 
>> That said, I agree with Benjamin that having an `apply` method for KeyPath 
>> seems like the right way to make (or have made) keypaths work. 
>> keypath.apply(to: instance) (or keypath.evaluate(on:), or some other name 
>> that gets the idea across) reads just as nice as instance[keyPath: keypath] 
>> and has the added benefit of allowing collection.map(keypath.apply) at no 
>> cost. But it’s probably too late to even bother having a discussion about 
>> this, right?
> 
> I don’t think so. That’s why we have a beta. Real-world experience has shown 
> that we would often like to erase a KeyPath and use it as if it were a 
> closure. Maybe we want to pass a KeyPath as a parameter to a function such as 
> “map", which accepts a closure, or we want to set a variable with a 
> closure-type using a KeyPath. Those functions and stored properties don’t 
> care about the special properties of KeyPaths (e.g. that they are Codable) - 
> they only care that they are executable on a base object to produce a result. 
> You can wrap the key-paths inside closures, but it’s cumbersome and some 
> developers are asking for a shorthand to perform that erasure.
> 
> Personally, I would be in favour of making the erasure implicit and allowing 
> KeyPaths to be invoked using function-syntax:
> 
> // Invocation using function-syntax:
> 
> let _: Value = someClosure(parameter)
> let _: Value = someKeypath(parameter)
> 
> let _: Value = { $0.something.anotherThing }(parameter)
> let _: Value = (\MyObj.something.anotherThing)(parameter)
> 
> // Implicit erasure to closure-type:
> 
> class PrettyTableCell {
> let titleFormatter: (T) -> String
> }
> let cell= PrettyTableCell()
> cell.titleFormatter = \MyObj.something.name
> 
> let stuff = myObjects.map(\.something.anotherThing)
> 
> - Karl
> 
>> 
>>> On Jul 11, 2017, at 6:27 PM, Karl Wagner <razie...@gmail.com 
>>> <mailto:razie...@gmail.com>> wrote:
>>> 
>>> 
>>>> On 11. Jul 2017, at 21:01, Robert Bennett via swift-evolution 
>>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>>>> 
>>>> In general, I like the idea of making ordinary types callable (although 
>>>> curried functions already accomplish this to some extent), but I hesitate 
>>>> to bring this capability to keypaths because, well, they don’t really feel 
>>>> like functions; I think the point of them is that they work like 
>>>> subscripts, not functions. After all, before keypaths were added, there 
>>>> was already an easy to make a function that does what a keypath does 
>>>> (which makes me wonder whether keypaths were necessary in the first place, 
>>>> but that ship has sailed). The only reason to add callable support to 
>>>> keypaths is for use in map, which I don’t think justifies making them 
>>>> callable.
>>>> 
>>>> Also, since I brought this up, I’d like to be proved wrong about keypaths 
>>>> – what use

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

2017-07-11 Thread Robert Bennett via swift-evolution
Well, if they really are first-class deferred method calls or member accesses, 
then do seem pretty function-y after all. Then again, if they were meant to be 
functions, it seems like their design would reflect that – instead of being 
used like subscripts, they would be called like functions, and since new syntax 
had to be created either way, the fact that they *weren't* just made into 
callable objects seems to indicate that that was not the intent, although I’d 
have to go back and read the discussion to see exactly what was discussed. 

That said, I agree with Benjamin that having an `apply` method for KeyPath 
seems like the right way to make (or have made) keypaths work. 
keypath.apply(to: instance) (or keypath.evaluate(on:), or some other name that 
gets the idea across) reads just as nice as instance[keyPath: keypath] and has 
the added benefit of allowing collection.map(keypath.apply) at no cost. But 
it’s probably too late to even bother having a discussion about this, right?

> On Jul 11, 2017, at 6:27 PM, Karl Wagner <razie...@gmail.com> wrote:
> 
> 
>> On 11. Jul 2017, at 21:01, Robert Bennett via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> In general, I like the idea of making ordinary types callable (although 
>> curried functions already accomplish this to some extent), but I hesitate to 
>> bring this capability to keypaths because, well, they don’t really feel like 
>> functions; I think the point of them is that they work like subscripts, not 
>> functions. After all, before keypaths were added, there was already an easy 
>> to make a function that does what a keypath does (which makes me wonder 
>> whether keypaths were necessary in the first place, but that ship has 
>> sailed). The only reason to add callable support to keypaths is for use in 
>> map, which I don’t think justifies making them callable.
>> 
>> Also, since I brought this up, I’d like to be proved wrong about keypaths – 
>> what use do they have that isn’t accomplished by the equivalent closure?
> 
> I can’t find a formal definition of a “keypath”, so let me explain how I 
> think of them:
> 
> Conceptually, I think I would define a KeyPath as a stateless, deferred 
> function application with one unbound argument (the “base"). Anything you do 
> with a KeyPath could be done with a closure of type (Base)->Value which 
> captures all other arguments (e.g. subscript/function parameters). The major 
> benefit that it has over a closure is identity (so you can put it in a 
> dictionary or compare two keypaths), and that property that captures all of 
> its parameters except the base, and that those parameters don’t have stateful 
> side-effects. That makes it really handy for parallel execution and database 
> predicates in ORMs.
> 
> There’s also another benefit of KeyPaths: they are de-/serialisable. Again, 
> since it captures all of its (stateless) parameters, it itself is stateless 
> and can be transferred to persistent storage or over a network.
> 
> You can actually see those constraints in the KeyPath proposal (which is part 
> of what makes it such a great proposal, IMO): all captured parameters must be 
> Hashable and Codable.
> 
> But to come back to your point - in all other respects a KeyPath is 
> conceptually identical to a closure of type (Base)->Value. It’s like a 
> specially-annotated closure, where it’s special construction syntax lets us 
> statically verify that it’s a stateless, deferred function applicable to an 
> instance of the Base type.
> 
> The KeyPath proposal said that eventually, the core team would like to be 
> able to support arbitrary function calls in KeyPath expressions, too. For 
> example, it’s "not fair” that \MyObject.firstFiveElements and \MyObject[3] 
> are valid KeyPaths, but \MyObject.prefix(5) is not. It’s also expressible as 
> (Base)->Value, so conceptually it’s also a KeyPath and can be serialised and 
> whatnot.
> 
> - Karl 
> 
>>> On Jul 11, 2017, at 2:28 PM, Benjamin Herzog via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> I still think using an operator for this conversation would neither 
>>> increase readability nor transparency. I think my mail on Sunday was lost, 
>>> so I paste the content here again. It referred to a suggestion to create a 
>>> possibility for KeyPath to act as a function which would bring other 
>>> benefits as well:
>>> 
>>> In Scala you can implement an apply method which makes it possible to call 
>>> an object just like a function. Example:
>>> 
>>> case class Foo(x: Int) {
>>>   def apply(y: Int) = x + y
>>> }
>>> 
>

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

2017-07-11 Thread Robert Bennett via swift-evolution
In general, I like the idea of making ordinary types callable (although curried 
functions already accomplish this to some extent), but I hesitate to bring this 
capability to keypaths because, well, they don’t really feel like functions; I 
think the point of them is that they work like subscripts, not functions. After 
all, before keypaths were added, there was already an easy to make a function 
that does what a keypath does (which makes me wonder whether keypaths were 
necessary in the first place, but that ship has sailed). The only reason to add 
callable support to keypaths is for use in map, which I don’t think justifies 
making them callable.

Also, since I brought this up, I’d like to be proved wrong about keypaths – 
what use do they have that isn’t accomplished by the equivalent closure?

> On Jul 11, 2017, at 2:28 PM, Benjamin Herzog via swift-evolution 
>  wrote:
> 
> I still think using an operator for this conversation would neither increase 
> readability nor transparency. I think my mail on Sunday was lost, so I paste 
> the content here again. It referred to a suggestion to create a possibility 
> for KeyPath to act as a function which would bring other benefits as well:
> 
> In Scala you can implement an apply method which makes it possible to call an 
> object just like a function. Example:
> 
> case class Foo(x: Int) {
> def apply(y: Int) = x + y
> }
> 
> val foo = Foo(3)
> val bar = foo(4) // 7
> 
> That is similar to what you suggested to have a possibility to convert an 
> object to a closure getting called. And I totally see the point for this! I 
> think using a keyword or special name like apply is not a good idea because 
> it's not obvious what it does and it also makes it possible to just call the 
> method with its name: foo.apply(4).
> 
> However, having a protocol is kinda hard because it's not possible to have a 
> flexible parameter list. Maybe having a method without a name? Swift example:
> 
> class Foo {
> var x: Int
> init(x: Int) { self.x = x }
>
> func (y: Int) -> Int {
> return self.x + y
> }
> }
> 
> let foo = Foo(x: 3)
> let bar = foo(y: 4) // 7
> 
> I actually like that, would be like an anonymous function. It would also be 
> possible to have multiple of those defined for one object (which would have 
> to be unambiguous of course).
> 
> So getting back to KeyPath, it could look like this:
> 
> class KeyPath {
> func (_ root: Root) -> Value {
> return root[keyPath: self]
> }  
> }
> 
> I see that this would be a much bigger change and would not justify the 
> syntactic sugar for map, flatMap, etc. But it would still be a nice addition 
> to the Swift programming language, especially for KeyPath, transformers etc.
> 
> What do you think?
> 
> __
> 
> 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] KeyPath based map, flatMap, filter

2017-07-11 Thread Robert Bennett via swift-evolution
This is also the case for $0, although I suppose that since $0 is only valid 
inside a closure, LLDB has some context with which to disambiguate Swift’s $0 
from LLDB’s, context it wouldn’t have with $keyPath. That said, there are 
probably solutions to this, like requiring a backslash before a Swift dollar 
sign to disambiguate from an LLDB dollar sign. Or something else. Designing the 
language with constraints imposed by the debugger seems unduly restrictive, 
though – surely the debugger should be subservient to the language, not the 
other way around.

> On Jul 11, 2017, at 12:44 PM, BJ Homer <bjho...@gmail.com> wrote:
> 
> ‘$' as a prefix is reserved for use by the debugger, so it cannot be used as 
> a conversion operator here.
> 
> -BJ
> 
>> On Jul 11, 2017, at 10:12 AM, Robert Bennett via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> It seems that there is some consensus that the proper way to achieve this is 
>> not to overload map et al. but to provide a way to convert KeyPath to a 
>> function. I agree – not only is this “cheaper”, as overloads of these 
>> functions will not need to be written, but it’s also more general and may 
>> prove useful in a context that we currently don’t foresee.
>> 
>> This being the case, I’ll repeat my proposal that the optimal way to achieve 
>> this is to make $ the conversion “operator” (although it need not, and 
>> probably should not, be a full-fledged operator), so that $keyPath –> { 
>> $0[keyPath: keyPath] }
>> 
>>> On Jul 11, 2017, at 11:13 AM, Elviro Rocca via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> 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<A,B> 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<A,B> 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 
>>>> <swift-evolution@swift.org> 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
>> ___
>> 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 Robert Bennett via swift-evolution
It seems that there is some consensus that the proper way to achieve this is 
not to overload map et al. but to provide a way to convert KeyPath to a 
function. I agree – not only is this “cheaper”, as overloads of these functions 
will not need to be written, but it’s also more general and may prove useful in 
a context that we currently don’t foresee.

This being the case, I’ll repeat my proposal that the optimal way to achieve 
this is to make $ the conversion “operator” (although it need not, and probably 
should not, be a full-fledged operator), so that $keyPath –> { $0[keyPath: 
keyPath] }

> On Jul 11, 2017, at 11:13 AM, Elviro Rocca via swift-evolution 
>  wrote:
> 
> 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
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Introduces endianness specific type

2017-07-09 Thread Robert Bennett via swift-evolution
Just a question: how would/does allowing the reordering of fields affect the 
correctness and performance of the (de)serialization API added in Swift 4?

> On Jul 9, 2017, at 6:21 PM, Jens Persson via swift-evolution 
>  wrote:
> 
> Thanks for that clarification John McCall.
> My code is using a lot of generic structs (in which memory layout is 
> important) though, an example would be:
> struct Vector4 : Vector {
> typealias Index = VectorIndex4
> typealias Element = E
> var e0, e1, e2, e3: Element
> …
> }
> And I guess I'm out of luck trying to represent those as C structs?
> So AFAICS it looks like it is currently impossible to write generic low level 
> code in Swift, unless I just keep doing what I've been doing (It does 
> currently work after all) knowing that it will probably break in some future 
> versions of Swift. But in that possible future version of Swift, I could 
> probably find a way to make it work again (using some possible explicit tools 
> for layout control present in that version of Swift).
> Correct?
> /Jens
> 
> 
>> On Sun, Jul 9, 2017 at 11:41 PM, John McCall  wrote:
>> 
>>> On Jul 9, 2017, at 4:49 PM, Jens Persson via swift-evolution 
>>>  wrote:
>>> 
>>> Sorry for making so much off topic noise in this thread, but I made a 
>>> mistake regarding the Metal tutorial:
>>> Looking more carefully I see now that they rebuild a vertedData: [Float] 
>>> from their vertices: [Vertex] using the floatBuffer() method of the Vertex 
>>> struct, which returns an Array with the stored properties of Vertex in 
>>> correct order.
>>> 
>>> While searching the internet about this I saw Joe Groff mentioning on 
>>> Twitter that:
>>> "We plan to sort fields in padding order to minimize size, and may also 
>>> automatically pack bools and enums in bitfields."
>>> 
>>> So AFAICS my current image processing code is making the possibly invalid 
>>> assumption that eg
>>> struct S {
>>> var a, b, c, d: Float
>>> }
>>> will have a memory layout of 4*4=16 bytes (stride and size == 16) and an 
>>> alignment of 4, and most importantly that a, b, c, d will be in that order.
>> 
>> This is currently true, but may not always be.  We want to reserve the right 
>> to re-order the fields even if it doesn't improve packing — for example, if 
>> two fields are frequently accessed together, field reordering could yield 
>> substantial locality benefits.  We've also discussed reordering fields to 
>> put them in a canonical order for resilience, since it's a little 
>> counter-intuitive that reordering the fields of a struct should be 
>> ABI-breaking.  (There are arguments against doing that as well, of course — 
>> for example, the programmer may have chosen the current order for their own 
>> locality optimizations.)
>> 
>>> It looks like I should be defining my structs (the ones for which memory 
>>> layout is important) in C and import them.
>> 
>> This should always work, yes.
>> 
>>> Although I would be surprised if a Swift-struct containing only same-sized 
>>> fields (all of the same primitive type) would be reordered, and such 
>>> changes to the language would probably include some per-struct way to 
>>> express some sort of layout control (since being able to define structs to 
>>> be used for low level data manipulation is important in a systems language).
>> 
>> Exactly.  In the long term, Swift will have some explicit tools for layout 
>> control.
>> 
>> John.
>> 
>>> 
>>> /Jens
>>> 
>>> 
 On Sun, Jul 9, 2017 at 7:01 PM, Jens Persson via swift-evolution 
  wrote:
 I should perhaps add that in my image processing code, I use code like 
 this:
 
 func withVImageBuffer(for table: Table, body: 
 (vImage_Buffer) -> R) -> R
 where
 Data.Coordinate.Index == VectorIndex2
 {
 let vib = vImage_Buffer(
 data: table.baseAddress,
 height: vImagePixelCount(table.size.e1),
 width: vImagePixelCount(table.size.e0),
 rowBytes: table.stride.e1
 )
 return withExtendedLifetime(table) { body(vib) }
 }
 
 Here, Table is the raster image. Data.Coordinate == VectorIndex2 
 makes it a 2D table, and a Table's Data also has a type parameter 
 Data.Value which can be eg one of the "pixel"-struct I showed before.
 This works without any problems (I've tested and used the some variant of 
 this type of code for years) but it would surely break if the memory 
 layout of simple structs changed.
 
 I can't see how this usage is much different from the one in the Metal 
 tutorial. It too uses pointers to point into a data created using the 
 (Swift) struct "Vertex", and the GPU hardware has its expectations on the 
 memory layout of that data, so the code would break if the memory layout 
 of the Vertex struct changed.
 
 /Jens

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

2017-07-08 Thread Robert Bennett via swift-evolution
I’m not sure about needing a universal promotion operator in Swift. However, in 
the case of KeyPaths, I think a leading $ (not currently a valid operator) 
would work well.

prefix operator $
prefix func $(rhs: KeyPath) -> (T)->U { return { $0[keyPath: rhs] } }

guys.map($\.name)

This reads really well to me because the $ is suggestive of the 
“functionization” of the KeyPath. Also, this is guaranteed to have no 
compatibility issues (right?) because it’s currently forbidden.

(I’m only suggesting giving the leading $ this functionality, not necessarily 
achieving this by making it a valid operator — in fact, it would probably be 
best if this functionality were “hard-coded” just as it is currently hard-coded 
for use in $0.)

> On Jul 8, 2017, at 5:46 PM, Benjamin Herzog via swift-evolution 
>  wrote:
> 
> Is this operator common in other languages? I would actually expect that the 
> conversation is not 'almost-implicit' but completely implicit instead. I 
> think both - a prefix and postfix operator - are not obvious enough what 
> happens here, especially because this kind of conversion is not happening in 
> other parts of the language.
> All conversions are implicit (from explicit type to protocol, from Swift 
> stdlib types to Objective-C types, from any type to Any, …) currently.
> 
> __
> 
> Benjamin Herzog
> 
>> On 8. Jul 2017, at 22:10, Hooman Mehr via swift-evolution 
>> > wrote:
>> 
>> I like this promote operator idea. I have been defining similar operators 
>> for specific projects almost at random. It makes sense to come up with a 
>> well-defined behavior and name for such operators, as a common practice as 
>> you suggest.
>> 
>> The problem with the postfix operator is that it does not currently work 
>> without an extra set of parenthesis:
>> 
>> postfix operator ^
>> 
>> postfix func ^(lhs: KeyPath) -> (T)->U { return { $0[keyPath: lhs] 
>> } }
>> 
>> struct Guy { let name: String }
>> 
>> let guys = [
>> Guy(name: "Benjamin"),
>> Guy(name: "Dave"),
>> Guy(name: "Brent"),
>> Guy(name: "Max")
>> ]
>> 
>> guys.map(\.name^) // Error: Invalid component of Swift key path
>> 
>> guys.map((\.name)^) // This works
>> 
>> Is this a bug? 
>> 
>> That is the reason I used a prefix operator (~) in my suggestion in the a 
>> previous e-mail on this thread.
> 
> ___
> 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-06 Thread Robert Bennett via swift-evolution
I agree with Brent (and others) that this is sugar worth having. If keypaths 
had been introduced earlier in the language’s evolution, array.map { 
$0.property } would look as ugly, and as Brent put it, as noisy, as array.map { 
f($0) }; we only accept it because we’ve had no better alternative. It feels as 
clunky to use a function to extract a property from a mapped element as it does 
to construct a closure whose only purpose is to call another function. If 
array.map(f) is allowed, then array.map(\.property) should be as well. It’s 
only natural.

That said, this addition does not necessarily need to occur soon. Xiaodi is 
right that once this is added, we’re pretty much stuck with it. Perhaps only 
after an evaluation of how keypaths are used by the Swift community should this 
addition to the language be reconsidered. There’s no need to permanently shelve 
the idea now, though. You get to eat dessert once you’ve eaten all your 
vegetables.

> On Jul 6, 2017, at 11:01 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> The lesson I took away from SE-0110 is that conveniences, once offered, are 
> disruptive to take away. People who don't delve deeply into the reasons that 
> make the conveniences unworkable in the grand scheme of things are upset when 
> these features are taken away because specific use cases are made less 
> ergonomic.
> 
> Since, as you say, subtyping is always a bit perilous, if this idea is 
> adopted but turns out to have important overlooked problems, trying to roll 
> it back is going to cause a lot of pain. Not offering it in the first place, 
> however, is by comparison only a slight inconvenience. No one has ever died 
> of not drinking alcohol; plenty have died of alcohol withdrawal. Therefore, 
> my lesson from SE-0110 is: vegetables now, vegetables forever.
> On Thu, Jul 6, 2017 at 21:38 Brent Royal-Gordon via swift-evolution 
>  wrote:
>>> On Jul 6, 2017, at 9:13 AM, Dave Abrahams  wrote:
>>> 
>>> I'm not sure what you're objecting to about this.  Is it the very
>>> appearance of curly braces?
>> 
>> 
>> I went to bed thinking that maybe I should have explained that better, and I 
>> guess I was right. ;^) Here's why I think we should do something here.
>> 
>> From what I can tell, mapping or filtering on a single property is 
>> exceptionally common. I ran a few regexes on the Swift code present on my 
>> machine (basically the stuff in the Swift repos, plus my open-source 
>> projects, plus my closed-source stuff, plus various playgrounds and things) 
>> to see how common different kinds of `map`, `filter`, and `flatMap` closures 
>> were:
>> 
>>  2142OP { …$0… }
>>  1835OP(function) or OP(some.method)
>>  589 OP { $0.property } or OP { $0.some.property }
>>  564 OP { $0.property }
>>  525 OP { function(…$0…) } or OP { some.method(…$0…) }
>>  186 OP { $0.method(…) }
>>  153 OP { function($0) } or OP { some.method($0) }
>>  100 OP { $0 as SomeType } or OP { $0 as? SomeType } or OP { 
>> $0 as! SomeType }
>>  52  OP { $0.method() }
>>  35  OP { collection[…$0…] } or OP { some.collection[…$0…] }
>>  20  OP { collection[$0] } or OP { some.collection[$0] }
>>  13  OP { $0! }
>> 
>> (Simple regex-based match of `map`, `flatMap`, and `filter` calls. Permits 
>> various spacing schemes and `try`. If you want to run it on a more 
>> representative sample, the script is here, requires fish(1): 
>> https://gist.github.com/brentdax/2a8ee2705c39e9948aafedbd81b1366f)
>>  
>> So, at least in my unscientific sample, more than a quarter of 
>> map/filter/flatMap calls which use `$0` simply look up a property or chain 
>> of properties on it. If we want to make something about `map` and friends 
>> more convenient, this seems like a good place to look.
>> 
>> (Using a straight function is a few times more common than a property, but 
>> given that this is also the syntax used to abstract over a closure body, I'm 
>> not sure how much weight to put on that fact.)
>> 
>> So what's wrong with what we have now? Syntactic weight. Consider this 
>> expression:
>> 
>>  person.map { $0.name }
>> 
>> The "loudest" parts of this expression are the closure brackets and the 
>> `$0`, but they are actually the *least* important. They do not express 
>> anything about what this line of code *does*; they exist solely to tell the 
>> compiler how to do it. They are pure glue code, and serve only to obscure 
>> the actual intent. Compare that to:
>> 
>>  person.map(\.name)
>> 
>> Here, we still have a glue character (the `\`), but it's just one, and it's 
>> relatively inconspicuous compared to something like `$0`.
>> 
>> That's not *too* bad, though. It gets a lot worse when the key path is 
>> actually in a variable:
>> 
>>  array.map { 

Re: [swift-evolution] Would having "MyType.Protocol" to indicate a type's protocols mess anything up?

2017-06-30 Thread Robert Bennett via swift-evolution
I’m not at a computer to test this, but would this work:

typealias T = P1 & P2
extension C: T {}

Now T is C.Protocol

> On Jun 30, 2017, at 9:17 PM, Daryle Walker via swift-evolution 
>  wrote:
> 
> 
>> On Jun 30, 2017, at 8:49 PM, Adrian Zubarev 
>>  wrote:
>> 
>> What are you proposing here, I don’t get it?! What role should .Protocol 
>> play? .Protocol is an ugly hack in Swift which should be removed anyway. It 
>> does more harm than good.
>> 
> I’m not proposing anything right now. I’m asking a question; the proposal 
> that needs the answer can be put off for later.
> 
> Given a type MyType, how can I get a type-alias to the type’s protocols? If 
> MyType conforms to Protocol1 and Protocol2, I would want something like
> 
>   typealias MyProtocol = Protocol1 & Protocol2
> 
> (and Any if MyType doesn’t conform to any protocols). Does this facility 
> already exist in Swift? I don’t think it does, so I proposed the hybrid 
> “MyType.Protocol” syntax to express the idea.
> 
> If you don’t like the current “.Protocol” syntax, then I guess you don’t like 
> it for this idea. I’m also requesting suggestions for alternate syntax.
> 
>   #protocols(MyType)
> 
> is an example.
> 
> I guess this should be a separate proposal from my other one.
>> Our revised proposal was deferred from Swift 4:
>> 
>> https://github.com/DevAndArtist/swift-evolution/blob/refactor_existential_metatypes/proposals/0126-refactor-metatypes.md
>> 
> 
> — 
> Daryle Walker
> Mac, Internet, and Video Game Junkie
> darylew AT mac DOT com 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-06-30 Thread Robert Bennett via swift-evolution
If/when Never is made a bottom time, I suppose this discussion will be moot 
because it will automatically work with ?? and the compiler would have to go 
out of its way to prevent that.

But until then, I much prefer guard-let-else to the proposed addition to ??. 
With a guard-let-else, the first word on the line tells you what’s going on, 
and when scanning through code you can quickly skim over that entire block as 
soon as you see “guard”. Guard-let-else makes it easy to understand the code at 
a glance. With the proposed addition to ??, you have to read all the way to the 
end of the line to understand that you’re exiting early with a fatal error. And 
in addition this lacks the flexibility of guard-let-else because you *must* 
fail; you cannot perform cleanup work and/or return gracefully.

While a convenient syntactic sugar, I foresee this addition making quickly 
understanding existing code much more difficult, and without much added 
convenience.

> On Jun 30, 2017, at 5:05 PM, Brent Royal-Gordon via swift-evolution 
>  wrote:
> 
>>> On Jun 30, 2017, at 5:38 AM, Matthew Johnson  wrote:
>>> 
>>> 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 `??`.
>> 
>> What do you have in mind here?  I don't recall any discussion of `throw` 
>> return Never.  It seems like a novel use of a bottom type that might 
>> preclude the possibility of ever having a Result type that seamlessly 
>> bridges to Swift's error handling.  
> 
> 
> `throw` is currently a statement. Imagine, for sake of illustration, that it 
> was instead a function. This function would take an `Error` as a parameter 
> and throw it. It would never return normally—it would only return by 
> throwing—so its return type would be `Never`:
> 
>   @_implicitlyTry
>   func throw(_ error: Error) throws -> Never {
>   try Builtin.throw(error)
>   unreachable()
>   }
> 
> What I'm suggesting is that `throw` should remain a keyword, but should have 
> the semantics of this `throw(_:)` function. The parser should allow it in 
> expression context, the `try` checker should treat it as though it was 
> already marked `try`, and the type checker should treat it as an expression 
> that returns `Never` but can throw.
> 
> That would then allow you to say things like:
> 
>   let lastItem = array.last ?? throw MyError.arrayEmpty
> 
> It would not have any negative effect I can think of on `Result`. In fact, 
> trying to directly wrap a `throw SomeError.foo` statement in a `Result` would 
> produce a `Result`, correctly expressing the fact that the 
> result of that particular expression can never be successful.
> 
> -- 
> Brent Royal-Gordon
> Architechies
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-06-28 Thread Robert Bennett via swift-evolution
Instead of adding “@autoclosure ()->Never” to ??, why not make that the role of 
!! ? This would both make it clear that the unwrap is unsafe, like !, but also 
provide flexibility in how to report the error. E.G., optional !! 
fatalError(“oops”) 

> On Jun 28, 2017, at 11:41 AM, Ben Cohen via swift-evolution 
>  wrote:
> 
> 
>> On Jun 28, 2017, at 8:27 AM, David Hart via swift-evolution 
>>  wrote:
>> 
>> Count me in as a strong proponent of ?? () -> Never. We don't need to burden 
>> the language with an extra operator just for that.
> 
> You could say the same about ??
> 
> The concern that an additional operator (and one that, IMO, fits well into 
> existing patterns) is so burdensome seems way overweighted in this discussion 
> IMO. 
> 
> Adding the operator, and encouraging its use, will help foster better 
> understanding of optionals and legitimate use of force-unwrapping in a way 
> that I don’t think `?? fatalError` could.
> 
> 
> ___
> 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] `let` in protocols

2017-06-25 Thread Robert Bennett via swift-evolution
For a concrete type, a partial initializer is a function that:
Can set `let` instance variables
May not refer to `self` in an rvalue
Must set the same subset of instance variables regardless of the code path taken

For a protocol, a partial initializer is simply a function that sets *any* 
subset of the instance variables. A protocol could provide a default 
implementation of one. In order for this `let` proposal to work, though, if a 
`let` variable is set in the protocol extension’s implementation of a (full) 
initializer, the protocol would need to provide at least one partial 
initializer that it does not provide an implementation for, so that a 
conforming type can fill in the gaps for all of the instance variables it 
defines that the protocol doesn’t require/know about. That way the compiler can 
have faith that a conforming type will be able to fully initialize itself with 
the default implementation of the required full initializer.


> On Jun 25, 2017, at 3:57 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> So your proposed definition of a partial initializer is one that does not set 
> any protocol requirement?
> On Sun, Jun 25, 2017 at 14:54 Robert Bennett <rltbenn...@icloud.com 
> <mailto:rltbenn...@icloud.com>> wrote:
> The compiler would only raise an error when a conforming type violated the 
> requirement that the partial initializer not set x. The protocol itself would 
> never fail to compile.
> 
> On Jun 25, 2017, at 3:33 PM, Xiaodi Wu <xiaodi...@gmail.com 
> <mailto:xiaodi...@gmail.com>> wrote:
> 
>> On Sun, Jun 25, 2017 at 2:24 PM, Robert Bennett via swift-evolution 
>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> You’re right Xiaodi, I did not entirely think this through. However I think 
>> this could still work with another addition to the language: partial 
>> initializers. These would be treated as initializers are now (meaning, for 
>> instance, no reference to self until initialization is complete) except they 
>> would only need to initialize a subset of the instance variables before 
>> exiting. An initializer could then satisfy the requirement that all instance 
>> variables must be initialized by calling partial initializers.
>> 
>> By incorporating partial initializers, it would be possible to guarantee 
>> that a `let` variable in a protocol is only set once. This is because an 
>> init implemented in a protocol extension could delegate to a partial 
>> initializers required by the protocol, and because they are only partial 
>> initializers, they need not set the instance variables already set in the 
>> initializer; it would be up to a conforming type to ensure this is the caee. 
>> A confirming type would define the partial initializer to set everything not 
>> already set in the protocol extension’s init, and it would be a compiler 
>> error to set a variable in the partial initializer that is already set in 
>> the extension’s init without overriding the extension’s init.
>> 
>> How can the compiler raise this error when the implementation of the partial 
>> initializer does not even have to exist at compile time?
>> 
>> Example code:
>> 
>> protocol P {
>> var x: Int { let } // or { get set(init) }, or whatever
>> 
>> partialinit initializeRest()
>> init()
>> }
>> 
>> extension P {
>> init() {
>> initializeRest()
>> 
>> How can the compiler ensure that `initializeRest()` does not already set `x`?
>>  
>> self.x = 1
>> }
>> }
>> 
>> struct S: P {
>> let x: Int
>> var y: String
>> 
>> // It would be a compiler error to set x here without also redefining 
>> init()
>> partialinit initializeRest() {
>> self.y = “P has no knowledge of me”
>> }
>> 
>> // Can use default init provided by P
>> }
>> 
>> > On Jun 23, 2017, at 8:12 PM, Karl Wagner <razie...@gmail.com 
>> > <mailto:razie...@gmail.com>> wrote:
>> >
>> > What you want is some way to guarantee value semantics when writing 
>> > generic code.
>> >
>> > It’s a known hole, and admittedly quite a big one. I hope that there will 
>> > be time for core language improvements like this in Swift 5. Be sure to 
>> > raise the issue again once planning for that starts!
>> >
>> > - Karl
>> >
>> >> On 23. Jun 2017, at 23:43, Robert Bennett via swift-evolution 
>> >> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:
>> >>
>> >>

Re: [swift-evolution] [Pitch] `let` in protocols

2017-06-25 Thread Robert Bennett via swift-evolution
The compiler would only raise an error when a conforming type violated the 
requirement that the partial initializer not set x. The protocol itself would 
never fail to compile.

> On Jun 25, 2017, at 3:33 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
>> On Sun, Jun 25, 2017 at 2:24 PM, Robert Bennett via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> You’re right Xiaodi, I did not entirely think this through. However I think 
>> this could still work with another addition to the language: partial 
>> initializers. These would be treated as initializers are now (meaning, for 
>> instance, no reference to self until initialization is complete) except they 
>> would only need to initialize a subset of the instance variables before 
>> exiting. An initializer could then satisfy the requirement that all instance 
>> variables must be initialized by calling partial initializers.
>> 
>> By incorporating partial initializers, it would be possible to guarantee 
>> that a `let` variable in a protocol is only set once. This is because an 
>> init implemented in a protocol extension could delegate to a partial 
>> initializers required by the protocol, and because they are only partial 
>> initializers, they need not set the instance variables already set in the 
>> initializer; it would be up to a conforming type to ensure this is the caee. 
>> A confirming type would define the partial initializer to set everything not 
>> already set in the protocol extension’s init, and it would be a compiler 
>> error to set a variable in the partial initializer that is already set in 
>> the extension’s init without overriding the extension’s init.
> 
> How can the compiler raise this error when the implementation of the partial 
> initializer does not even have to exist at compile time?
> 
>> Example code:
>> 
>> protocol P {
>> var x: Int { let } // or { get set(init) }, or whatever
>> 
>> partialinit initializeRest()
>> init()
>> }
>> 
>> extension P {
>> init() {
>> initializeRest()
> 
> How can the compiler ensure that `initializeRest()` does not already set `x`?
>  
>> self.x = 1
>> }
>> }
>> 
>> struct S: P {
>> let x: Int
>> var y: String
>> 
>> // It would be a compiler error to set x here without also redefining 
>> init()
>> partialinit initializeRest() {
>> self.y = “P has no knowledge of me”
>> }
>> 
>> // Can use default init provided by P
>> }
>> 
>> > On Jun 23, 2017, at 8:12 PM, Karl Wagner <razie...@gmail.com> wrote:
>> >
>> > What you want is some way to guarantee value semantics when writing 
>> > generic code.
>> >
>> > It’s a known hole, and admittedly quite a big one. I hope that there will 
>> > be time for core language improvements like this in Swift 5. Be sure to 
>> > raise the issue again once planning for that starts!
>> >
>> > - Karl
>> >
>> >> On 23. Jun 2017, at 23:43, Robert Bennett via swift-evolution 
>> >> <swift-evolution@swift.org> wrote:
>> >>
>> >> Hello Swift Evolution,
>> >>
>> >> I’m bumping into an annoying problem with protocols. In a class or struct 
>> >> it is common to have a `let` instance variable and assign it in `init`. 
>> >> Unfortunately there is no way to translate this into a protocol with init 
>> >> in an extension. If attempting to set the variable in init in an 
>> >> extension, it must be of type { get set }, which means it cannot be a 
>> >> `let` constant in the conforming type. AFAIK there is no way around this 
>> >> — if you want to set an instance variable in an initializer in a protocol 
>> >> extension, it must be marked as { get set }. The alternative is to write 
>> >> the initializer separately for each adopting type, but this violates DRY.
>> >>
>> >> Hence, I am proposing a third option to go along with `get` and `set` in 
>> >> a protocol. This would indicate that the variable can be a constant, but 
>> >> is settable in an initializer. In this case, the conforming type *must* 
>> >> use `let` to declare the variable.
>> >>
>> >> Option 1: the keyword `let`. If present, it would need to be the only 
>> >> thing in the curly brackets because it simultaneously implies `get` and 
>> >> not `set`.
>> >>
>> >> protocol P {
>> >>   var 

Re: [swift-evolution] [Pitch] `let` in protocols

2017-06-25 Thread Robert Bennett via swift-evolution
You’re right Xiaodi, I did not entirely think this through. However I think 
this could still work with another addition to the language: partial 
initializers. These would be treated as initializers are now (meaning, for 
instance, no reference to self until initialization is complete) except they 
would only need to initialize a subset of the instance variables before 
exiting. An initializer could then satisfy the requirement that all instance 
variables must be initialized by calling partial initializers.

By incorporating partial initializers, it would be possible to guarantee that a 
`let` variable in a protocol is only set once. This is because an init 
implemented in a protocol extension could delegate to a partial initializers 
required by the protocol, and because they are only partial initializers, they 
need not set the instance variables already set in the initializer; it would be 
up to a conforming type to ensure this is the caee. A confirming type would 
define the partial initializer to set everything not already set in the 
protocol extension’s init, and it would be a compiler error to set a variable 
in the partial initializer that is already set in the extension’s init without 
overriding the extension’s init. Example code:

protocol P {
var x: Int { let } // or { get set(init) }, or whatever

partialinit initializeRest()
init()
}

extension P {
init() {
initializeRest()
self.x = 1
}
}

struct S: P {
let x: Int
var y: String

// It would be a compiler error to set x here without also redefining init()
partialinit initializeRest() {
self.y = “P has no knowledge of me”
}

// Can use default init provided by P
}

> On Jun 23, 2017, at 8:12 PM, Karl Wagner <razie...@gmail.com> wrote:
> 
> What you want is some way to guarantee value semantics when writing generic 
> code.
> 
> It’s a known hole, and admittedly quite a big one. I hope that there will be 
> time for core language improvements like this in Swift 5. Be sure to raise 
> the issue again once planning for that starts!
> 
> - Karl
> 
>> On 23. Jun 2017, at 23:43, Robert Bennett via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> Hello Swift Evolution,
>> 
>> I’m bumping into an annoying problem with protocols. In a class or struct it 
>> is common to have a `let` instance variable and assign it in `init`. 
>> Unfortunately there is no way to translate this into a protocol with init in 
>> an extension. If attempting to set the variable in init in an extension, it 
>> must be of type { get set }, which means it cannot be a `let` constant in 
>> the conforming type. AFAIK there is no way around this — if you want to set 
>> an instance variable in an initializer in a protocol extension, it must be 
>> marked as { get set }. The alternative is to write the initializer 
>> separately for each adopting type, but this violates DRY.
>> 
>> Hence, I am proposing a third option to go along with `get` and `set` in a 
>> protocol. This would indicate that the variable can be a constant, but is 
>> settable in an initializer. In this case, the conforming type *must* use 
>> `let` to declare the variable.
>> 
>> Option 1: the keyword `let`. If present, it would need to be the only thing 
>> in the curly brackets because it simultaneously implies `get` and not `set`.
>> 
>> protocol P {
>>   var x: Int { let }
>>   init(_ x: Int)
>>   func modifyX()
>> }
>> extension P {
>>   init(_ x: Int) {
>>   self.x = x // This is ok; would not be ok if x were marked { get }
>>   }
>> 
>>   func modifyX() {
>>   self.x += 1 // Not allowed
>>   }
>> }
>> 
>> struct S: P {
>>   let x: Int // This is ok; would not be ok if x were marked { get set }
>> }
>> 
>> Option 2: `set(init)`. Can (and often will) coexist with `get`.
>> 
>> protocol P {
>>   var x: Int { get set(init) }
>>   init(_ x: Int)
>>   func modifyX()
>> }
>> extension P {
>>   init(_ x: Int) {
>>   self.x = x // This is ok; would not be ok if x were marked { get }
>>   }
>> 
>>   func modifyX() {
>>   self.x += 1 // Not allowed
>>   }
>> }
>> 
>> struct S: P {
>>   let x: Int // This is ok; would not be ok if x were marked { get set }
>> }
>> 
>> 
>> I’d like to hear all of your thoughts on this.
>> 
>> Best,
>> Robert
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [Pitch] `let` in protocols

2017-06-23 Thread Robert Bennett via swift-evolution
Hello Swift Evolution,

I’m bumping into an annoying problem with protocols. In a class or struct it is 
common to have a `let` instance variable and assign it in `init`. Unfortunately 
there is no way to translate this into a protocol with init in an extension. If 
attempting to set the variable in init in an extension, it must be of type { 
get set }, which means it cannot be a `let` constant in the conforming type. 
AFAIK there is no way around this — if you want to set an instance variable in 
an initializer in a protocol extension, it must be marked as { get set }. The 
alternative is to write the initializer separately for each adopting type, but 
this violates DRY.

Hence, I am proposing a third option to go along with `get` and `set` in a 
protocol. This would indicate that the variable can be a constant, but is 
settable in an initializer. In this case, the conforming type *must* use `let` 
to declare the variable.

Option 1: the keyword `let`. If present, it would need to be the only thing in 
the curly brackets because it simultaneously implies `get` and not `set`.

protocol P {
var x: Int { let }
init(_ x: Int)
func modifyX()
}
extension P {
init(_ x: Int) {
self.x = x // This is ok; would not be ok if x were marked { get }
}

func modifyX() {
self.x += 1 // Not allowed
}
}

struct S: P {
let x: Int // This is ok; would not be ok if x were marked { get set }
}

Option 2: `set(init)`. Can (and often will) coexist with `get`.

protocol P {
var x: Int { get set(init) }
init(_ x: Int)
func modifyX()
}
extension P {
init(_ x: Int) {
self.x = x // This is ok; would not be ok if x were marked { get }
}

func modifyX() {
self.x += 1 // Not allowed
}
}

struct S: P {
let x: Int // This is ok; would not be ok if x were marked { get set }
}


I’d like to hear all of your thoughts on this.

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


Re: [swift-evolution] a few initializer proposals

2017-06-22 Thread Robert Bennett via swift-evolution
I think an even stronger change should be made for #1: instead of explicitly 
opting into not discarding the default initializer, you should have to 
explicitly opt out of keeping it with something like @nosynthesizedinit. Unless 
I’m missing something and there is a compelling reason to remove the default 
initializer when you’ve provided another initializer.

I agree with #2 as is.

For #3, I imagine there’s some reason classes don’t get synthesized 
initializers. Probably because they’re meant to encapsulate a lot more 
functionality than merely maintaining state. Even if a class had an init with 
the “default” signature, it would almost certainly do more in the body than 
just assign them to instance variables. Since structs are so frequently used to 
simply hold onto state/keep data around, it makes sense for the compiler to 
provide an initializer that takes the entire initial state/set of data. In 
other words: if you find yourself using such an initializer for a class (an 
initializer that merely assigns the arguments to instance variables), you 
probably want to make that class a struct.

> On Jun 22, 2017, at 9:38 AM, Bastiaan Marinus van de Weerd via 
> swift-evolution  wrote:
> 
> Strongly +1 on proposals #1 and #2. Cautiously +1 on #3 (I’m not sure about 
> side effects there).
> 
> If #1 is already possible as Jon Shier says using an extension, I’d say it 
> deserves promotion to be part of the language (e.g. Mike’s proposed `default 
> init`), or at least should be made more discoverable (e.g. using a Fix-It on 
> an implementation equivalent to the default initializer).
> 
> 
> –Bastiaan
> 
>> On Wed, Jun 21, 2017 at 8:00 PM, Jon Shier via swift-evolution 
>>  wrote:
>> 1 can already be accomplished by moving the custom initializer into an 
>> extension. 
>> 
>> 
>> Jon
>> 
>>> On Jun 21, 2017, at 7:42 PM, Mike Kluev via swift-evolution 
>>>  wrote:
>>> 
>>> hi. here are a few somewhat related initializer proposals for your 
>>> consideration.
>>> they are designed as "opt-ins" so shall not break existing code.
>>> 
>>> * proposal 1 *
>>> have an ability to keep default initializers in structs
>>> 
>>> struct S {
>>> var int: Int
>>> var float: Float
>>> var bool: Bool
>>> }
>>> 
>>> here default initializer is currently generated:
>>> 
>>> struct S {
>>> var int: Int
>>> var float: Float
>>> var bool: Bool
>>> 
>>> //  autogenerated:
>>> //  init(int: Int, float: Float, bool: Bool) {
>>> //  self.int = int
>>> //  self.float = float
>>> //  self.bool = bool
>>> //  }
>>> }
>>> 
>>> so we can write:
>>> 
>>> let s = S(int: 0, float: 0, bool: false)
>>> 
>>> so far so good. now i want to add a "convenience" initializer. i don't want 
>>> the default initializer to go away though:
>>> 
>>> struct S {
>>> var int: Int
>>> var float: Float
>>> var bool: Bool
>>> 
>>> /* convenience */ init(x: Int) {
>>> self.init(int: 0, float: 0, bool: false) // *** ERROR. this 
>>> initializer is gone
>>> }
>>> }
>>> 
>>> let s = S(x: 0)
>>> let s = S(int: 0, float: 0, bool: false) // *** ERROR. this initializer is 
>>> gone
>>> 
>>> this may be convenient in some cases but not others.
>>> proposal: introduce an opt-in construct to keep the default initializer 
>>> intact:
>>> 
>>> struct S {
>>> var int: Int
>>> var float: Float
>>> var bool: Bool
>>> 
>>> default init // explicit opt-in. suggest a better name
>>> 
>>> /* convenience */ init(x: Int) {
>>> self.init(int: 0, float: 0, bool: false) // still ok
>>> }
>>> }
>>> 
>>> let s = S(x: 0) // ok
>>> let s = S(int: 0, float: 0, bool: false) // still ok
>>> 
>>> 
>>> * proposal 2 *
>>> have the default initializer to have default nil values for all optional 
>>> parameters in structs
>>> 
>>> struct S {
>>> var int: Int
>>> var float: Float?
>>> var bool: Bool
>>> 
>>> //  autogenerated:
>>> //  init(int: Int, float: Float? = nil, bool: Bool) {
>>> //  self.int = int
>>> //  self.float = float
>>> //  self.bool = bool
>>> //  }
>>> }
>>> 
>>> in the extreme case:
>>> 
>>> struct S5 {
>>> var int: Int?
>>> var float: Float?
>>> var bool: Bool?
>>> 
>>> //  autogenerated:
>>> //  init(int: Int? = nil, float: Float? = nil, bool: Bool? = nil) {
>>> //  self.int = int
>>> //  self.float = float
>>> //  self.bool = bool
>>> //  }
>>> }
>>> 
>>> usage:
>>> S(float: 3)
>>> S()
>>> S(int: 0, float: 0, bool: false)
>>> 
>>> note that this is still "opt-in" as the old code will be using the full 
>>> form anyway and not break.
>>> 
>>> * proposal 3 *
>>> introduce a similar opt-in default initialiser for classes:
>>> 
>>> class C {
>>> var int: Int
>>> var float: Float?
>>> var bool: Bool
>>> }
>>> 
>>> let c = C(int: 0, float: 0, bool: false) // *** ERROR
>>> 
>>> class C {
>>> 

Re: [swift-evolution] In-line scope designators

2017-06-19 Thread Robert Bennett via swift-evolution
+1 for member variables, -1 for member functions. Functions take up too much 
vertical space to make this convenient; you’d constantly be scrolling around to 
view or modify the access level of a function. Plus I tend to group functions 
by use — private functions go directly above the public function that calls 
them. But member declarations are often one or just a few lines, and 
additionally are often grouped by access level anyway (at least that’s how I do 
it) so this provides a compact way to group them.


> On Jun 17, 2017, at 5:48 PM, Ted F.A. van Gaalen via swift-evolution 
>  wrote:
> 
> (I am not sure if I should tag this subject with [pitch]? ) 
> 
> Please don’t worry , I am not attempting to start a new
> and infinite thread about whether or not the way scope
> is handled in Swift is imho correct or not.
> Errhm well, apart from that “protected” is missing,
> but please let us not start again.. :o) 
> 
> No, it is more or less a convenience solution to
> prevent unnecessary wear and tear to the following keys
> on my keyboard: [ A,E, I, P,  R, T, V]
> 
> I prefer it, not to expose those class or struct members
> which should not be accessible outside the class or struct
> 
> Currently, to prevent access to private Items,
> I have to type the word “private” too many times:
> 
> class  House
> {
> private var rooms = 5
>   private var roofTiles = 11201
>   private let paint =   UIColor.Blue;
> private var yearTax: Money = “323,56"
> private let garageVolume = 60.0
> 
> init(..) {.. }
> 
>  private func calculateTax() {...}
> 
>  public func roomsUnoccupied() -> Int {…}
> 
> func roofData(……) {…}
> 
>  private func  a{…} 
> }
> 
> To set the scope of a list of members I suggest the
> “in-line scope modifiers”  (anyone with a better name for it?) 
> 
> For example if one has a source line containing the word
> “private:” then all the following member declarations will
> be “private” until another inline scope modifier is encountered
> with one “default scope” to escape from it. like in the following example”
> 
> The compiler can detect that it is an inline scope modifier, because it ends 
> with a colon
> 
> “Normal” scope modifiers, that is the ones which precede the member’s name 
> directly should imho not be allowed within such a scope block.
> unless they would override for that specific item, but that looks ugly. 
> 
> getter & setters and init should appear in default scope
> (or with no in-line scope modifiers)
> 
> Inline scope modifiers can be specified as often as
> desired and in arbitrary sequence. 
> 
> 
> class  House
> {
>  init(..) {.. }
> private:// <——  In-line scope 
> modifier all following declarations are private here.
> var rooms = 5
>   var roofTiles = 11201
>   let paint =   UIColor.Blue;
> var yearTax: Money = “323,56"
> func calculateTax() {…}
> func  a{…} 
> 
>   public: // <——  In-line 
> scope modifier
>  var garageVolume = 60.0  
>  func roomsUnoccupied() -> Int {…}
>  func roofData(……) {…}
> 
>   defaultscope: // <—— Return to default 
> scope (only needed when preceding inline scope modifiers are present. )
>  
>   func sellHouse(buyer: CustomerID)   
> }
> 
> See? looks a lot better, don’t you think so?  
> it also makes sources more readable because one can 
> now conveniently group items.
> 
> 100% source compatible with whatever scope 
> mechanism now or in the future is or will be deployed.
> 
> 
> (The idea is not exactly new, a similar construct is available in Object 
> Pascal.)  
> 
> ?
> 
> Kind Regards
> TedvG
> 
> 
> 
> 
> 
> 
>  
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution

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


Re: [swift-evolution] Revisiting SE-0110

2017-06-15 Thread Robert Bennett via swift-evolution
> One (tangential) thing that came up is that tuple element names in tuple 
> *patterns* should probably be deprecated and removed at some point.  Without 
> looking, what variables does this declare?:
> 
>   let (a : Int, b : Float) = foo()


I think it would be better if the compiler raised a warning whenever you tried 
to redefine a builtin type. `let (a : Int, b : Float) = foo()` is confusing but 
if you were to use your own type (e.g., `struct S {}` and replace Int and Float 
with S) you would get a compiler error. If the compiler warned you that you 
were reassigning Int and Float, you’d probably avoid that problem. Or, for a 
more extreme fix, we could make reassigning builtin types illegal since there 
is pretty much no valid reason to do that.


> On Jun 15, 2017, at 8:10 AM, Matthew Johnson via swift-evolution 
>  wrote:
> 
> 
> 
> Sent from my iPad
> 
>> On Jun 14, 2017, at 11:01 PM, Chris Lattner via swift-evolution 
>>  wrote:
>> 
>> 
>>> On Jun 12, 2017, at 10:07 PM, Paul Cantrell  wrote:
>>> 
>>> What’s the status of this Chris’s double parens idea below? It garnered 
>>> some positive responses, but the discussion seems to have fizzled out. Is 
>>> there something needed to help nudge this along?
>>> 
>>> What’s the likelihood of getting this fixed before Swift 4 goes live, and 
>>> the great wave of readability regressions hits?
>> 
>> We discussed this in the core team meeting today.  Consensus seems to be 
>> that a change needs to be made to regain syntactic convenience here.  
>> Discussion was leaning towards allowing (at least) the parenthesized form, 
>> but more discussion is needed.
>> 
>> 
>> One (tangential) thing that came up is that tuple element names in tuple 
>> *patterns* should probably be deprecated and removed at some point.  Without 
>> looking, what variables does this declare?:
>> 
>>   let (a : Int, b : Float) = foo()
> 
> Another option would be to require let to appear next to each name binding 
> instead of allowing a single let for the whole pattern.  I personally find 
> that much more clear despite it being a little bit more verbose.
> 
>> 
>> ?
>> 
>> -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

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


Re: [swift-evolution] [Pitch] Introducing role keywords to reduce hard-to-find bugs

2017-06-14 Thread Robert Bennett via swift-evolution
I like this proposal a lot and also like Xiaodi’s suggestion that these be made 
into @ attributes.

> On Jun 14, 2017, at 1:48 PM, Xiaodi Wu via swift-evolution 
>  wrote:
> 
> I like that this is minimal impact because it is optional. Since it is 
> optional, I wonder if making it visually distinct from the mandatory keywords 
> such as "override" for classes would be optimal, perhaps by making these 
> @annotations.
> 
> Otherwise the naming is near perfect, IMO. It follows by analogy with 
> `override` and `convenience`. There is one nit here that `override func` 
> reads well in two senses: it's an overriding function with a certain 
> signature _and_ it's overriding a function with that signature. Moreover, 
> "override" can be read as a noun (a nouned verb, but plausibly a noun 
> nonetheless), fitting in better with "convenience" and "default." By 
> contrast, an `extend func` would be an extending function _but_ it's not 
> extending a function, so it may read more awkwardly. It's also definitely not 
> a noun. Might it be possible simply to reuse the keyword `extension` in this 
> context?
> 
> As to the overall design, I like this much better than all previous 
> alternatives, which are amply discussed in your proposal text.
> 
> 
>> On Wed, Jun 14, 2017 at 12:11 PM, Erica Sadun via swift-evolution 
>>  wrote:
>> Some pals and I have been kicking an idea around about introducing better 
>> ways to support the compiler in protocol extensions. We want to eliminate 
>> some hard-to-detect bugs. We've been brainstorming on how to do this without 
>> affecting backward compatibility and introducing a minimal impact on 
>> keywords. 
>> 
>> We'd love to know what you think of our idea, which is to introduce "role" 
>> keywords. Roles allow the compiler to automatically check the intended use 
>> of a extension member definition against its protocol declarations, and emit 
>> errors, warnings, and fixits as needed.  We think it's a pretty 
>> straightforward approach that, if adopted, eliminates an entire category of 
>> bugs.
>> 
>> The draft proposal is here: 
>> https://gist.github.com/erica/14283fe18254489c1498a7069b7760c4
>> 
>> Thanks in advance for your thoughtful feedback,
>> 
>> -- E
>> 
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Proposal] Change Void meaning

2017-06-13 Thread Robert Bennett via swift-evolution
I think Xiaodi’s “problem” is that he’s so knowledgeable of everything that’s 
happened on this list that when he sees efforts move in what he – usually 
correctly, I think – perceives to be an unproductive direction he points it out 
instead of letting the list spin its wheels or rehash old ideas that have 
already been settled. (Sorry to talk about you in the third person Xiaodi)

> On Jun 13, 2017, at 7:09 AM, Jérémie Girault via swift-evolution 
>  wrote:
> 
> For clarity and improvement, could you please post a sample where an 
> ambiguity could happen? I can't think of the issue here.
> I think that type-safety can still be conserved.
> 
> —
> very short reply expected - vsre.info
> Jérémie Girault
> 
>> On 13 juin 2017 at 11:06:54, Florent Bruneau via swift-evolution 
>> (swift-evolution@swift.org) wrote:
>> 
>> 
>> > Le 13 juin 2017 à 10:41, Xiaodi Wu via swift-evolution 
>> >  a écrit :
>> > 
>> >> On Tue, Jun 13, 2017 at 3:06 AM, John McCall  wrote:
>> >>> On Jun 13, 2017, at 3:30 AM, Jérémie Girault  
>> >>> wrote:
>> >>> 
>> >>> Exactly, 
>> >>> The reflexion behind it is: 
>> >>> 
>> >>> - Let's understand that 0110 and other tuple SE are important for the 
>> >>> compiler, we do not want them to rollback
>> >>> - However we have number of regressions for generics / functional 
>> >>> programmers
>> >>> - Let’s solve this step by step like a typical problem
>> >>> 
>> >>> - Step 0 is adressing this Void tuple of size zero :
>> >>> - Zero is in many problems of CS an edge case, so let’s handle this case 
>> >>> first
>> >>> - The compiler knows what Void is, and its only value (or non-value)
>> >>> - It was handled historically by the compiler because of implicit side 
>> >>> effects
>> >>> - Let’s handle it explicitely with rules in current context
>> >>> - one effect of the proposal is source compatibility
>> >>> - but the goal is to build atop and strengthen 0110, 0066 and other 
>> >>> tuple-related SE
>> >>> 
>> >> 
>> >> There are four difficulties I see with this proposal.
>> >> 
>> >> The first is that it is a first step that quite clearly does not lead to 
>> >> anything. It resolves a difficulty with exactly one case of function 
>> >> composition, but we would need completely different solutions to handle 
>> >> any of the other compositional regressions of SE-0110.
>> >> 
>> >> The second is that it's a huge source of complexity for the type system. 
>> >> The type checker would not be able to do even rudimentary type matching, 
>> >> e.g. when checking a call, without having first resolved all of the 
>> >> argument and parameter types to prove that they are not Void. This would 
>> >> probably render it impossible to type-check many programs without some 
>> >> ad-hoc rule of inferring that certain types are not Void. It would 
>> >> certainly make type-checking vastly more expensive.
>> >> 
>> >> The third is that it is not possible to prevent values of Void from 
>> >> existing, because (unlike Never, which cannot be constructed) they are 
>> >> always created by returning from a Void-returning function, and a generic 
>> >> function can do anything it likes with that value — turn it into an Any, 
>> >> store it in an Array, whatever. The proposal seems to only consider using 
>> >> the value as a parameter.
>> >> 
>> > Hang on, though. If Jérémie is interested only in addressing the issue of 
>> > Void as a parameter and his idea can be adequately carried out by 
>> > inferring a default value of Void for every parameter of type Void, this 
>> > should be a fairly self-contained change, should it not? And would the 
>> > impact on the cost of type checking really be vastly greater in that case?
>> > 
>> > This idea is now rather intriguing to me because it extends beyond just 
>> > addressing one symptom of SE-0110. Swift allows us to omit the spelling 
>> > out of return types that are Void, it allows warning-free discarding of 
>> > return values that are Void, etc. This could add a nice consistency and 
>> > rationalize some of the weirdness of passing a value that is stipulated by 
>> > the parameter type.
>> > 
>> >> Finally, it would allow a lot of inadvertent errors with the use of 
>> >> generic functions, because any argument of unconstrained type could be 
>> >> accidentally specialized with Void. For example, if you forgot to pass an 
>> >> argument to this function, it would simply infer T=Void:
>> >> func append(value: T)
>> >> It seems more likely that this would lead to unexpected, frustrating bugs 
>> >> than that this would actually be desired by the programmer. You really 
>> >> just want this to kick in in more generic situations.
>> >> 
>> > Hmm, at first glance, that seemed like it could be bad. But if, say, a 
>> > particular collection can store an element of type Void, is it so 
>> > undesirable to allow `append()` to append Void?
>> 
>> Seems to me the 

Re: [swift-evolution] [Proposal] Change Void meaning

2017-06-12 Thread Robert Bennett via swift-evolution
The name Unit is used in Foundation for that exact meaning: 
https://developer.apple.com/documentation/foundation/unit 
.

I like the name `Nothing` for the empty tuple. func foo(Nothing) {}


> On Jun 12, 2017, at 1:57 PM, David Sweeris via swift-evolution 
>  wrote:
> 
> 
> On Jun 12, 2017, at 10:44, Jérémie Girault via swift-evolution 
> > wrote:
> 
>> Void was the empty tuple because arguments were tuples. So no arguments 
>> meant empty tuple.
>> 
>> If we consider the empty tuple to be an argument, then the type for the type 
>> of empty tuple should be `Unit`
>> 
>> Void, however, seem naturally fitted for the absence of argument.
>> 
>> Should `func foo(Void)` be different from `func foo()`? I don’t think so. 
>> But different from `func foo(Unit)` ? Yes !
>> 
> To me, "Unit" is used like "a unit of length", "a unit of time", etc. I've 
> not come across it being used as analog for something like the empty tuple.
> 
> - Dave Sweeris
> ___
> swift-evolution mailing list
> swift-evolution@swift.org 
> https://lists.swift.org/mailman/listinfo/swift-evolution 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Introduction of OrderedSet

2017-06-09 Thread Robert Bennett via swift-evolution
I recall reading that in Python 3.6 they changed the implementation of set and 
dict to both have better performance *and* maintain insert order for free. I 
know nothing about the implementation details of this but might it be possible 
to make a similar change to Swift’s Set and Dictionary, so that we don’t even 
need specialized ordered variants?

> On Jun 9, 2017, at 7:28 PM, Douglas Gregor <dgre...@apple.com> wrote:
> 
> 
>> On Jun 9, 2017, at 10:19 AM, Xiaodi Wu via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> Let me try to redirect this conversation, if I may.
>> 
>> As far as I can tell, SE-0069 states plainly that the plan of record is to 
>> offer a value type called OrderedSet in Foundation, but resources to design 
>> and implement were not then available.
>> 
>> So, little point in having a vote as to whether one is in favor of 
>> OrderedSet or not. In my view, the questions to be answered are:
>> 
>> For the core team–
>> 
>> * Is it still the plan to offer value types postponed from SE-0069 as a 
>> future addition to Foundation?
> 
> *I* think it’s still a good idea, and I suspect that others on the core team 
> will agree.
> 
>> * If so, is that a priority in the Swift 5 timeframe, and how can the 
>> community help to bring about this addition?
> 
> I wouldn’t consider it a “priority”, in the sense that I can’t imagine 
> anything in Swift 5 that would absolutely require us to introduce this 
> functionality in that time frame. It’s a bit of a nice-to-have-at-any-point, 
> noting of course that bridging NSOrderedSet in existing APIs is a nontrivial 
> source-breaking change.
> 
> Having a proposed API and implementation on hand makes it easier to add this 
> functionality, of course.
> 
>> If not, for the whole community–
>> 
>> * Is it wise to implement such a type in the standard library? Should we 
>> simply bring over the native implementation from Swift Package Manager? What 
>> are the implications for bridging?
> 
> Obviously, we’d want an efficient copy-on-write, native implementation; the 
> Swift Package Manager implementation is a bit more bare-bones than we’d want: 
> absolute performance matters, so having a separate Set + Array in the struct 
> probably isn’t good enough. Bridging performance matters, so we’d probably 
> want the one-pointer representation like array uses where the pointer can be 
> vended directly to Objective-C.
> 
>   - Doug
> 
>>> On Fri, Jun 9, 2017 at 11:38 Remy Demarest via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> +1 for ordered set and dictionary, and please add ordered dictionary in 
>>> ObjC as well.
>>> 
>>> Envoyé de mon iPhone
>>> 
>>>> Le 9 juin 2017 à 03:11, Robert Bennett via swift-evolution 
>>>> <swift-evolution@swift.org> a écrit :
>>>> 
>>>> +1, and would also like to see OrderedDictionary as well.
>>>> 
>>>>> On Jun 9, 2017, at 12:50 AM, Jeff Kelley via swift-evolution 
>>>>> <swift-evolution@swift.org> wrote:
>>>>> 
>>>>> I would be in favor of it; there have been a few times (including Core 
>>>>> Data, as you mentioned) where I would have used it had it been available.
>>>>> 
>>>>> 
>>>>> Jeff Kelley
>>>>> 
>>>>> slauncha...@gmail.com | @SlaunchaMan | jeffkelley.org
>>>>> 
>>>>>> On Jun 7, 2017, at 2:10 PM, Maik Koslowski via swift-evolution 
>>>>>> <swift-evolution@swift.org> wrote:
>>>>>> 
>>>>>> Hello,
>>>>>> 
>>>>>> in the past there have been a few requests for an OrderedSet 
>>>>>> implementation in Swift. In the proposal 
>>>>>> https://github.com/apple/swift-evolution/blob/master/proposals/0069-swift-mutability-for-foundation.md
>>>>>>  was mentioned that the OrderedSet will be considered for the feature.
>>>>>> 
>>>>>> However, since then there were a few discussions on OrderedSet but it 
>>>>>> doesn’t get much attention and there wasn’t any comment about it from 
>>>>>> the swift team.
>>>>>> 
>>>>>> I want to bring up some points, why an OrderedSet is needed in the base 
>>>>>> library.
>>>>>> 
>>>>>> 1. CoreData is probably the most obvious place where people would use an 
>>>>>> ordered set. Especially when w

Re: [swift-evolution] History and future of Swift's parentheses

2017-06-09 Thread Robert Bennett via swift-evolution
I see. My ideal solution to this would be an explicit tuple packing and 
unpacking API, as opposed to implicitly flexible functions. Something akin to 
(borrowing Python’s asterisk syntax):

func compose(_ g: (*U)->*V, _ f: (*T)->*U) -> (*T)->*V {...}

The asterisks indicate that the arguments to the function will be packed into a 
tuple (or not, in the case of a single-argument function) whose type is denoted 
by T, U, V, or conversely that the functions take/return argument lists that 
look like *T, *U, *V where T, U, V are tuple types. Then the function 
definition would look like

{
return { x: *T in g(f(x)) }
}

This would in essence create a new non nominal type: function argument lists. 
These would be distinct from tuples, although the two may freely be converted 
into one another using the asterisk. This type would be structurally distinct 
from tuples by virtue of the fact that single-element argument lists exist 
while single-element tuples do not. (An asterisk will convert a single-element 
argument list into a single (non-tuple) element and vice versa.)

To users, argument lists would be accessed solely through tuples with the 
asterisk syntax. The identity **T == T would hold whenever T is a tuple or 
argument list. Their usefulness would lie in the ability to call f(*x) when f 
takes multiple arguments and x is a tuple.

I acknowledge that this is probably not going to happen for Swift 4 but I would 
sure like it if it did.

> On Jun 9, 2017, at 5:10 PM, Jens Persson via swift-evolution 
>  wrote:
> 
> The point of exercise 1 is to show that it is impossible (in Swift 4) to 
> write a generic function composition operator (or function) which works as 
> expected for any reasonable functions.
> This was possible in Swift 3, but in Swift 4 it will only work for functions 
> with exactly one parameter. You'd have to special-case it for every 
> combination of parameter counts of f and g that it should be able to handle.
> 
> The following program demonstrates how it can be done in Swift 3.1 and 3.2:
> 
> func compose(_ g: @escaping (U) -> V, _ f: @escaping (T) -> U) -> 
> (T) -> V {
> return { x in g(f(x)) }
> }
> func sum(_ a: Int, _ b: Int) -> Int { return a + b }
> func square(_ a: Int) -> Int { return a * a }
> let squaredSum = compose(square, sum)
> let result = squaredSum((3, 4)) // A bit unexepected with a tuple here but ok 
> ...
> print(result) // 49
> // Well, it worked, not flawlessly but we did manage to write
> // a function composition function and we composed sum
> // and square, and we could call it and get a correct result.
> 
>  
> And this program demonstrates what happens if you try it in Swift 4:
> 
> func compose(_ g: @escaping (U) -> V, _ f: @escaping (T) -> U) -> 
> (T) -> V {
> return { x in g(f(x)) }
> }
> func sum(_ a: Int, _ b: Int) -> Int { return a + b }
> func square(_ a: Int) -> Int { return a * a }
> // let squaredSum = compose(square, sum) // Error! (without the 
> compose-variant below)
> 
> // The error message is:
> // Cannot convert value of type `(Int, Int) -> Int` to
> // expected argument type `(_) -> _`
> 
> // That's it, it is simply not possible!
> 
> // You'd have to write special variants of the compose func for every 
> combination
> // of parameter counts! For example, in order to get this sum and square
> // example working, this specific variant must be written:
> func compose(_ g: @escaping (V) -> W, _ f: @escaping (T, U) -> V) 
> -> (T, U) -> W {
> return { (x, y) in g(f(x, y)) }
> }
> // Now it will work:
> let squaredSum = compose(square, sum)
> // But only thanks to that awfully specific compose func variant ...
> // We would have to write a lot more variants for it to be practically usable 
> on pretty much any common function.
> 
> I'm sure some will say:
> "no regular developers use function composition anyway so why ..."
> or
> "It's not very swifty to use free functions and higher order functions like 
> that."
> 
> My answer is that this is just a simple but telling example. The issue (as I 
> see it) exists in all situations involving generics and function types.
> 
> I'm a regular programmer and I like to be able to write basic, useful 
> abstractions.
> It's no fun when the language forces you to write lots of specific variants 
> of your generic code.
> 
> I would feel less worried about the parentheses situation if the language was 
> going in a direction where you could see how this simple exercise would be a 
> no brainer.
> 
> Can Swift's parentheses-situation be sorted out before ABI stability?
> Otherwise it would be a bit like if Swift had kept the special rule for the 
> first parameter, only much worse.
> 
> /Jens
> 
> 
> 
> 
>> On Fri, Jun 9, 2017 at 7:17 PM, Gor Gyolchanyan  wrote:
>> Yes, except why would you need to define `((A, B)) -> C`?, If you need to 
>> pass a 2-element tuple into a function that takes two 

Re: [swift-evolution] Pitch: Limit typealias extensions to the typealias

2017-06-09 Thread Robert Bennett via swift-evolution
Somewhat related to this, shouldn’t it be possible to sub-struct a struct as 
long as you only add functions and computed properties (i.e., no stored 
properties)? Traditionally structs cannot be subtyped because their size must 
be known at compile time. I don’t know the implementation details of where 
functions and computed properties live, but something tells me they belong to 
the type and not the object (although I’ve never really made the effort to sit 
down and fully understand Swift’s type model), in which case adding them to a 
struct’s definition would not change the size of the object on the stack. Thus 
it should be possible to make custom substructs of String that add additional 
functionality but no new stored properties. Thoughts?

> On Jun 9, 2017, at 12:12 PM, Jacob Williams via swift-evolution 
>  wrote:
> 
>> On Jun 9, 2017, at 9:53 AM, Charlie Monroe  wrote:
>> 
>> -1 - this would disallow e.g. to share UI code between iOS and macOS:
>> 
>> #if os(iOS)
>>  typealias XUView = UIView
>> #else
>>  typealias XUView = NSView
>> #endif
>> 
>> extension XUView {
>>  ...
>> }
> 
> I really don’t see how this disallows code sharing between the two systems? 
> Could you explain further? Based on my understanding of the pitch, this is 
> valid code still. (Although I do like the suggestion of a new keyword rather 
> than just limiting type alias).
> 
> Even if your example was invalid, you could also just do something like this:
> 
> #if os(iOS)
>   typealias XUView = UIView
>   extension XUView {
>   //extension code here
>   }
> #if os(macOS)
>   typealias XUView = UIView
>   extension XUView {
>   // extension code here
>   }
> #endif
> 
> While not as pretty, still just as effective if you have to deal with 
> different types based on the system being compiled for and you could easily 
> still make the type alias extensions for each type work the same.
> 
>> On Jun 9, 2017, at 9:53 AM, Charlie Monroe  wrote:
>> 
>> -1 - this would disallow e.g. to share UI code between iOS and macOS:
>> 
>> #if os(iOS)
>>  typealias XUView = UIView
>> #else
>>  typealias XUView = NSView
>> #endif
>> 
>> extension XUView {
>>  ...
>> }
>> 
>> or with any similar compatibility typealiases.
>> 
>>> On Jun 9, 2017, at 5:38 PM, Jacob Williams via swift-evolution 
>>>  wrote:
>>> 
>>> +1 from me.
>>> 
>>> There have been times I’ve wanted to subclass an object (such as String) 
>>> but since it is a non-class, non-protocol type you can only extend Strings 
>>> existing functionality which adds that same functionality to Strings 
>>> everywhere. It would be nice if we could either extend type aliases (and 
>>> only the type alias), or if it were possible to inherit from structs so 
>>> that we could create a custom string type like so:
>>> 
>>> struct HeaderKey: String {
>>> static var lastModified: String { return “Last-Modified” }
>>> static var host: String { return “Host” }
>>> }
>>> 
>>> I realize that struct inheritance is far less likely, since that defeats 
>>> one of the main pieces of what makes a struct a struct. So I’m all for this 
>>> proposal of allowing type aliases to be extended as though they were their 
>>> own struct/class.
>>> 
>>> Unfortunately, I’m not sure how feasible this kind of functionality would 
>>> actually be, but if it’s possible then I’m in favor of implementing it.
>>> 
 On Jun 8, 2017, at 10:14 PM, Yvo van Beek via swift-evolution 
  wrote:
 
 Typealiases can greatly reduce the complexity of code. But I think one 
 change in how the compiler handles them could make them even more powerful.
 
 Let's say I'm creating a web server framework and I've created a simple 
 dictionary to store HTTP headers (I know that headers are more complex 
 than that, but as an example). I could write something like this:
 
 typealias HeaderKey = String
 
   var headers = [HeaderKey: String]()
   headers["Host"] = "domain.com"
 
 Now I can define a couple of default headers like this:
 
   extension HeaderKey {
 static var lastModified: String { return "Last-Modified" }
 static var host: String { return "Host" }
   }
 
 After that I can do this:
 
   var headers = [HeaderKey: String]()
   headers[.host] = "domain.com"
   headers[.lastModified] = "some date"
   headers["X-MyHeader"] = "This still works too"
 
 But unfortunately the extension is also applied to normal strings:
 
 var normalString: String = .host
 
 Perhaps it would be better if the extension would only apply to the parts 
 of my code where I use the HeaderKey typealias and not to all Strings. 
 This could be a great tool to specialize classes by creating a typealias 

Re: [swift-evolution] History and future of Swift's parentheses

2017-06-09 Thread Robert Bennett via swift-evolution

At first I thought that task 1 looked innocuous enough; then I discovered this 
bizarre behavior. Not sure if this was the point of your email. 

func compose(_ g: @escaping (U)->V, _ f: @escaping (T)->U) -> (T)->V {
return { x in g(f(x)) }
}

func strung(_ tuple: (Int, Int)) -> (String, String) {
return ("\(tuple.0)", "\(tuple.1)")
}

func concat(_ tuple: (String, String)) -> String {
return tuple.0 + tuple.1
}

print(String(reflecting: compose(concat, strung)(3, 4))) // "34"; but shouldn't 
we need a tuple?
print(String(reflecting: compose(concat, strung)((3, 4 // "34"; this makes 
sense

let f = compose(concat, strung)
print(String(reflecting: f(3, 4))) // ERROR: extra argument in call; but if the 
first line works, shouldn't this too?
print(String(reflecting: f((3, 4 // "34"; also makes sense

On Jun 07, 2017, at 03:03 PM, Jens Persson via swift-evolution 
 wrote:

Swift uses parentheses for a lot of different things (tuples, parameters, 
calls, grouping, pattern matching, etc), this has led to some confusion, for 
both language designers and users.

Here's a practical introduction that is possibly worth more than a thousand 
words (or perhaps even swift-evo posts):

  Exercise 1
    Write a (generic) function composition operator in Swift 4
    (working as expected for all function types).

  Exercise 2
    Write a generic type WrappedFunction that can wrap any function in Swift 4
    (with type parameters for Input and Output).

When you have completed (or given up) the exercises, please note that once in 
the history of Swift, these were simple tasks. You could come up with working 
solutions very quickly without any boilerplate or special casing (although 
perhaps not entirely without some of the parentheses-related inconsistencies of 
that time).

I've been reporting a lot of parentheses-related bugs since the first Swift 
beta, and I'm only getting more and more worried that the current incremental 
approach to fixing these is not working very well, resulting in a language that 
is more complex and less expressive than it could be.

Discussions often seem to end up being a bit too focused on particular use 
cases and details, and less on how everything fit together as a system.


So I wonder if any of you have had any thoughts about what Swift's 
parentheses-related future (or evolutionary baggage) will be?


PS

My perhaps unpopular thoughts:

I wish the parentheses-related parts of Swift could be carefully evaluated and 
redesigned from scratch, as a whole, in order to arrive at a solution that is 
as simple and expressive as possible.

But perhaps this has already happened and we are now just taking some steps 
back that are necessary for reimplementing some of the good stuff (that has 
been - at least IMHO - sort of hinted in earlier versions of Swift). But it 
feels like there is not enough time ...

Swift, please break my code all you want before it's too late, as long as it 
results in increased (rather than decreased) consistency, simplicity, 
expressiveness, optimizability and safety. Otherwise I could have used 
Objective C++. 

/Jens

___
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] Introduction of OrderedSet

2017-06-09 Thread Robert Bennett via swift-evolution
+1, and would also like to see OrderedDictionary as well.

> On Jun 9, 2017, at 12:50 AM, Jeff Kelley via swift-evolution 
>  wrote:
> 
> I would be in favor of it; there have been a few times (including Core Data, 
> as you mentioned) where I would have used it had it been available.
> 
> 
> Jeff Kelley
> 
> slauncha...@gmail.com | @SlaunchaMan | jeffkelley.org
> 
>> On Jun 7, 2017, at 2:10 PM, Maik Koslowski via swift-evolution 
>>  wrote:
>> 
>> Hello,
>> 
>> in the past there have been a few requests for an OrderedSet implementation 
>> in Swift. In the proposal 
>> https://github.com/apple/swift-evolution/blob/master/proposals/0069-swift-mutability-for-foundation.md
>>  was mentioned that the OrderedSet will be considered for the feature.
>> 
>> However, since then there were a few discussions on OrderedSet but it 
>> doesn’t get much attention and there wasn’t any comment about it from the 
>> swift team.
>> 
>> I want to bring up some points, why an OrderedSet is needed in the base 
>> library.
>> 
>> 1. CoreData is probably the most obvious place where people would use an 
>> ordered set. Especially when working with large amounts of data, presorting 
>> can save a lot of time and battery life. If a bridgeable ordered set was 
>> part of the standard library we could use a ordered set in swift without 
>> having to use the NSOrderedSet from objective c. Which would be pretty nice 
>> in my opinion. Even when using a NSOrderedSet we couldn’t have a generic 
>> version of it.
>> 
>> 2. A shared datamodel between App and Server. One main advantage of having 
>> web servers written in Swift is that we can share code between the server 
>> and the app. For servers performance does matter a lot, since they are 
>> usually working with much more data than apps. Databases are represented as 
>> sets and fetching sorted data from the database can be represented as an 
>> ordered set. However, since we don’t have ordered sets we have to choose 
>> either a normal set or an array. Sets don’t have an order and arrays can 
>> contain the same object multiple times, which makes them both a less 
>> suitable choice.
>> 
>> 3. Swift has the potential to be used for education. There is a lot of 
>> support, for example the playground app on iPad. When it comes to the theory 
>> behind data structures and algorithms or to the theory of computation a 
>> defined order plays an important role.
>> 
>> The biggest issue is that we always have to copy data from a set into an 
>> array to have it in a sorted order with losing the safety of uniqueness. 
>> Which is not suitable for a safe and performance oriented programming 
>> language at all.
>> 
>> Last but not least, it fits in the goals of Swift 4 stage 2 and an ordered 
>> set can be found in other popular programming languages, too.
>> 
>> What do you think?
>> 
>> Best regards,
>> 
>> Maik
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Proposal: Always flatten the single element tuple

2017-06-08 Thread Robert Bennett via swift-evolution
I’m personally a fan of strictness and maximum consistency. I like the idea of 
flattening single element tuples down to the deepest thing contained that is 
not a single element tuple. So (x) flattens to x and x,y flattens to 
the tuple (x,y). Past SEs have dictated that you may not flatten a tuple down 
into a list of arguments.

For function types, it’s a rule that you wrap the arguments in an extra set of 
parentheses, so (Int)->Int maps one Int to one Int; (Int, Int)->Int maps two 
(separate) Ints to Int; ((Int,Int))->Int and Int,Int->Int both map a 
2-tuple of Ints to Int. Int->Int is obviously not allowed.

Now, for closures, I think we should just apply the same principles. Require 
parentheses for the arguments, which means double parentheses (or more) are 
needed when unwrapping a tuple.

In my view cognitive load is a big part of ergonomics. Reducing the rule set to 
a single principle seems very ergonomic to me.

P.S. Maybe the compiler should also ban unnecessarily nested tuples, for 
clarity. Just a thought.

> On Jun 8, 2017, at 5:05 PM, Vladimir.S via swift-evolution 
>  wrote:
> 
> On 08.06.2017 21:17, Gwendal Roué via swift-evolution wrote:
>>> Le 8 juin 2017 à 19:40, Brent Royal-Gordon via swift-evolution 
>>> > a écrit :
>>> 
 On Jun 7, 2017, at 3:03 AM, Adrian Zubarev via swift-evolution 
 > wrote:
 
 Well please no:
 
> |let fn2: ((Int, Int)) -> Void = { lhs, rhs in }|
 
 Instead use destructuring sugar pitched by Chris Lattner on the other 
 thread:
 
 |let fn2: ((Int, Int)) -> Void = { ((lhs, rhs)) in }|
 
>>> I think this suggestion is better than the status quo. I'm wondering, 
>>> though, if we should just drop the outer set of parentheses entirely, 
>>> unless you're also putting types on the parameters. That is, a closure of 
>>> type `(Int, Int) -> T` can look like this:
>>> 
>>> { (x: Int, y: Int) in … }
>>> 
>>> Or it can look like this:
>>> 
>>> { x, y in … }
>>> 
>>> But it *cannot* look like this:
>>> 
>>> { (x, y) in … }
>>> 
>>> The `(x, y)` form can instead be a closure of a type like `((Int, Int)) -> 
>>> T`, which immediately destructures the tuple parameter into separate 
>>> constants.
>>> 
>>> -- 
>>> Brent Royal-Gordon
>>> Architechies
>> Hello,
>> There's a difference, in the mind of people here that try to show how bad 
>> were the recent changes, between:
>> 1: closures defined independently
>> 2: closures given as a parameter to a function.
>> I think that we all agree that the type of a closure that is defined 
>> independently should be well defined:
>> // Choose between (Int, Int) -> () or ((x: Int, y: Int)) -> ()
>> leta = { (x: Int, y: Int) -> Intin... }
>> letb = { ((x: Int, y: Int)) -> Intin... }
>> However, when a closure is given as an argument of a function that expects a 
>> closure, we ask for the maximum possible flexibility, as Swift 3 did:
>> funcwantsTwoArguments(_closure: (Int, Int) -> Int) { closure(1, 2) }
>> wantsTwoArguments{ a, b ina + b }
>> wantsTwoArguments{ (a, b) ina + b }
>> wantsTwoArguments{ t int.0+ t.1} // OK, maybe not
>> funcwantsATupleArgument(_closure: ((Int, Int)) -> Int) { closure((1, 2)) }
>> wantsATupleArgument{ a, b ina + b }
>> wantsATupleArgument{ (a, b) ina + b }
>> wantsATupleArgument{ t int.0+ t.1}
>> funcwantsANamedTupleArgument(_closure: ((lhs: Int, rhs: Int)) -> Int) { 
>> closure((lhs: 1, rhs: 2)) }
>> wantsANamedTupleArgument{ a, b ina + b }
>> wantsANamedTupleArgument{ (a, b) ina + b }
>> wantsANamedTupleArgument{ t int.lhs + t.rhs }
> 
> It's nice to see that we are agreed that func/closures declared separately 
> should have clearly defined type and (at least for now) can't be 
> interchangeable.
> 
> And personally I agree that this could be a solution to migration problem, 
> compiler can generate closure of correct(requested) type if such closure:
> 1. declared inplace of func call as parameter of that func
> 2. has no type annotations for its arguments
> 3. (probably, can discuss) has no parenthesis for its arguments, because one 
> pair of parenthesis in argument list declares closure of type (list of 
> arguments)->T in other situations.
> 
> So, we can have
> 
> wantsTwoArguments{ a, b in a + b } // (Int,Int)->() will be generated
> wantsTwoArguments{ (a, b) in a + b } // syntax of (Int,Int)->() closure
> 
> wantsATupleArgument{ a, b in a + b } // ((Int,Int))->() will be generated
> wantsATupleArgument{ t in t.0+ t.1 } // syntax of ((Int,Int))->() closure
> 
> wantsANamedTupleArgument{ a, b in a + b } // ((Int,Int))->() will be generated
> wantsANamedTupleArgument{ t in t.lhs + t.rhs } // syntax of ((Int,Int))->() 
> closure
> 
> So, { a,b in ...} will be a special syntax for closure which type will be 
> defined by compiler by type of func's parameter.
> 
> The question is if community and 

Re: [swift-evolution] Yet another fixed-size array spitball session

2017-06-02 Thread Robert Bennett via swift-evolution
My favorite proposal so far is one that was posted a while ago, [Int * 4]. I 
think that this syntax looks pretty Swifty. There isn't an oddball subscript 
operator like with Int[4], and there isn't a need to allow generics to support 
values as parameters. It's clear that [Int * 4] will be array-like and contain 
four Ints. For multidimensional arrays we could use [Int * (2,3)]. For an array 
of tuples, [(x: Int, y: Int) * 4]. I'm not sure why nested static arrays would 
be needed when multidimentionality is provided out of the box, but presumably 
the syntax would support them; you would just need to subscript the arrays one 
at a time instead of with a single subscript operator, e.g., a[i][j] instead of 
a[i, j].

I'm imagining this syntax working like [T] does now as a shorthand for 
Array, although I'm not sure what [Int * 4] should be short for 
(StaticArray? Vector4? ...). Constructors for static arrays would 
be called using [Int * 4](args). I'm thinking the constructors would be [T * 
4](filledWith: T), [T * 4](filledBy: (Int)->T), and an initializer taking a 
Sequence that fails in some manner on a dimension mismatch.


> On Jun 1, 2017, at 7:36 AM, Haravikk via swift-evolution 
>  wrote:
> 
> Just wanted to add my two-cents to this discussion, but in terms of syntax I 
> think that the basic method for specifying size should be with some kind of 
> type variables, like so:
> 
>   struct MyFixedArray { … }
> 
> The idea being that we can then use size as a variable anywhere within the 
> code for MyFixedArray, but unlike other variables it is determined at compile 
> time, so should be optimised accordingly. As with generics, setting a type 
> variable effectively creates a variant type so for example, a 
> MyFixedArray and a MyFixedArray would no longer be 
> directly compatible as they may differ internally.
> 
> This would be useful not just for fixed arrays, but other possibly type 
> variations as well. Ideally it should be possible to specify a default value 
> for type variables; while this wouldn't be useful for fixed arrays, it may be 
> useful for other type variants.
> 
> To better suit the specific use-case of arrays, we could also add some useful 
> attributes or keywords, for example, reusing subscript could give us:
> 
> struct MyFixedArray { … }
> let foo:MyFixedArray[4] = [1, 2, 3, 4] // with T being inferred, this is a 
> shorthand for specifying a size of 4
> 
> Type variables could also be usable with generics, like-so:
> 
> // only accept fixed arrays of same or smaller size:
> func myMethod(values:FA) where FA:FixedArray, FA.size <= Self.size { … } 
> 
> These are the kind of general purpose capabilities I'd like to see at some 
> point, as the usefulness extends beyond just fixed-size arrays.
> 
> 
> 
> However, on the  subject of fixed-size arrays specifically, one other 
> possibility to explore is the concept of Tuple repetition and subscripting. 
> For example, it would be interesting if we could do things like:
> 
>   var foo:(Int)[4] = 0 // Initialises four Ints, all set initially to zero
>   for i in 0 ..< 4 { foo[i] = i } // values are no 0, 1, 2, 3
> 
> This can be especially interesting when you get into more complex tuples like 
> so:
> 
>   var bar:(x:Int, y:Int)[10] = (x: 0, y: 0) // Initialises 10 pairs of 
> Ints, all initially set to zero
>   for i in 0 ..< 10 { bar[i].x = i; bar[i].y = i } // here we need to use 
> .x and .y to access the values of each pair
> 
> Of course this would have the same performance characteristics as standard 
> tuples, but it's an interesting means for creating quick, fixed-size arrays 
> in a flexible way. Part of the idea here is that by subscripting tuples, we 
> avoid the need for a general subscript on all types, keeping that available 
> for use-cases like the above.
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Revisiting SE-0110

2017-05-31 Thread Robert Bennett via swift-evolution
Seeing this makes me rethink the severity of this problem. I wonder if it would 
be worth it to add a starMap function that works like map, but unpacks tuples 
into separate arguments. So dict.map { (key, value) in ... } is still illegal 
but dict.starMap { (key, value) in ... } works like dict.map used to.

On May 31, 2017, at 5:02 PM, Stephen Celis  wrote:

>> On May 28, 2017, at 7:04 PM, John McCall via swift-evolution 
>>  wrote:
>> 
>> Yes, I agree.  We need to add back tuple destructuring in closure parameter 
>> lists because this is a serious usability regression.  If we're reluctant to 
>> just "do the right thing" to handle the ambiguity of (a,b), we should at 
>> least allow it via unambiguous syntax like ((a,b)).  I do think that we 
>> should just "do the right thing", however, with my biggest concern being 
>> whether there's any reasonable way to achieve that in 4.0.
> 
> Closure parameter lists are unfortunately only half of the equation here. 
> This change also regresses the usability of point-free expression.
> 
>   func add(_ x: Int, _ y: Int) -> Int {
> return x + y
>   }
> 
>   zip([1, 2, 3], [4, 5, 6]).map(add)
> 
>   // error: nested tuple parameter '(Int, Int)' of function '(((_.Element, 
> _.Element)) throws -> _) throws -> [_]' does not support destructuring
> 
> This may not be a common pattern in most projects, but we heavily use this 
> style in the Kickstarter app in our functional and FRP code. Definitely not 
> the most common coding pattern, but a very expressive one that we rely on.
> 
> Our interim solution is a bunch of overloaded helpers, e.g.:
> 
>   func tupleUp(_ f: (A, B) -> C) -> ((A, B)) -> C {
> return 
>   }
> 
>   zip([1, 2, 3], [4, 5, 6]).map(tupleUp(add))
> 
> Stephen
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Yet another fixed-size array spitball session

2017-05-31 Thread Robert Bennett via swift-evolution
Without static arrays, swift cannot be used in high performance applications. 
The cost of repeated heap accesses is simply too high. And tuples are not 
ergonomic enough to use in the same manner as arrays. So I think we do need to 
add static arrays to Swift, if not necessarily in Swift 4.

My suggestion: have two constructors, StaticArray(size: LiteralInteger, 
initialValue: T) and StaticArray(dimensions: [LiteralInteger], initialValue: 
T), one for the single-dimension case and one for the multidimensional case. By 
LiteralInteger I mean that the compiler rejects cases where the arguments are 
not integer literals, the same way it rejects non-literal values for enum 
cases. We should let the compiler turn calls of those constructors into 
stack-allocated static arrays behind the scenes. This could be as simple as 
synthesizing the code for a static array (see the gist I linked to). I don't 
really think we need any specialized syntax for this aside from the compiler 
limiting what can be passed to the constructor.

> On May 31, 2017, at 10:38 AM, Charlie Monroe via swift-evolution 
>  wrote:
> 
> 
>>> On May 31, 2017, at 4:16 PM, Jean-Daniel  wrote:
>>> 
>>> 
 Le 31 mai 2017 à 01:47, Anders Kierulf  a écrit :
 
 
> On May 30, 2017, at 3:36 PM, Jean-Daniel via swift-evolution 
>  wrote:
> 
> 
> Le 30 mai 2017 à 12:42, Charlie Monroe via swift-evolution 
>  a écrit :
> 
> There was someone a few weeks ago trying to port his Go game to Swift 
> from (I believe) C++ and found out that the lack of fixed-size arrays was 
> causing the move-computing algorithm to slow down significantly.
> 
> This is due to fixed arrays being able to live on stack, while "normal 
> Array" is dynamically allocated on heap, etc.
 
 Really ? Isn’t it due to the value semantic of swift arrays ?
 
 If this is the former, its algorithm can probably be tweak to reuse the 
 array and require less allocations.
 
 Unless if you algorithm is eager in memory allocation/deallocation, you 
 shouldn't get a significant difference between static array and dynamic 
 array.
>>> 
>>> Eliminating the dynamic allocations and extra indirections caused by the 
>>> Swift array implementation can make a huge difference, not just in itself, 
>>> but it also gives the compiler more opportunities to optimize the code.
>> 
>> I don’t see how static sized array would solve that issue.
>> 
>> If swift wants to keep value semantic it has to support COW or a similar 
>> machinery. 
>> If you want to avoid COW and force the array to be allocated on the stack, 
>> it will impose swift to copy it at each function boundary (there is no 
>> @unescape for array to tell the compiler it can safely pass a reference).
>> 
>> If what you want is just a preallocated array with reference semantic, wrap 
>> it in a class. You should get the same speed up than when using imported C 
>> arrays.
> 
> Creating an Array in Swift immediately makes a heap allocation. You then get 
> COW semantics, but you already made a heap allocation (unless the array is 
> empty).  
> 
> https://github.com/apple/swift/blob/master/stdlib/public/core/ContiguousArrayBuffer.swift#L208
> 
> With sized arrays, they can live on stack and the compiler can access the 
> elements by referencing the stack frame (quick access), vs. the array, where 
> it needs to dereference the pointer. Not to mention that the compiler can 
> actually make some elements accessible via registers.
> 
> Might seem like a small gain, but if you are making something that needs to 
> compute really fast, even getting 2x speed is fast (and accessing heap via 
> Array is more than 2x compared to accessing something on the stack). Not to 
> mention if you create a lot of arrays (e.g. matrix computations), creating a 
> static-sized array means just adding the size to the stack pointer.
> 
> 
> ___
> 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] Yet another fixed-size array spitball session

2017-05-30 Thread Robert Bennett via swift-evolution
I agree that Swift absolutely needs a static array type.

However, until then, here's a gist to generate the code for a static array 
struct: https://gist.github.com/rltbennett/8a750aa61d58746b3ca4531b3ca3d0db . 
Happy coding. (Disclaimer: barely tested.)


> On May 30, 2017, at 11:27 AM, David Sweeris via swift-evolution 
>  wrote:
> 
> 
>>> On May 30, 2017, at 03:25, Pavol Vaskovic  wrote:
>>> 
>>> On Tue, May 30, 2017 at 7:51 AM, David Sweeris  wrote:
>>> 
>>> `(Int, Int, Int, Int)` isn't *that* horrible compared to "[Int x 4]", but 
>>> would you want to replace "[Int8 x 1]" with the multipage-long tuple 
>>> equivalent?
>> 
>> 
>> It would be really helpful to my understanding, if you spoke about a 
>> practical use case. This reads as a contrived counterexample to me…
>> 
>> If your type really has 10 000 values in it, why does it have to be static, 
>> why doesn't normal Array fit the bill?
> 
> Sure, I meant it as an example of how unwieldy large tuples can be. Even 
> medium ones, really. Tuples are great for bundling a few values, but much 
> more than that any they become annoying to work with because there's no easy 
> way to iterate through them. As a more realistic example, what if you want a 
> stack-allocated 256-element buffer (which is a real possibility since 
> statically-allocated C arrays are imported as tuples)? You have to manually 
> keep track of i, because you have to hard-code which element you're 
> addressing ("buf.0", "buf.1", etc), rather than being able to look it up 
> directly from an index variable like, well, an array ("buf[i]").
> 
> Plus the fact that they can't conform to protocols really limits their 
> usefulness in filling the role of a "normal" type. For instance, even though 
> you could easily create the normal, 64-bit hash value from an instance of a 
> `(Int32, Int32)` simply by concatenating the two elements' bits, you can't 
> create a `Dictionary<(Int32, Int32), SomeType>` because there's no mechanism 
> to get `(Int, Int)` to conform to Dictionary's `Hashable` requirement.
> 
> Could both of these features get added to Tuples? From a technically PoV, 
> sure, and it's been discussed in previous threads. IMHO we'd get more benefit 
> out of adding support for variadic generic parameters and using literal 
> values as generic parameters (both of which have also been previously 
> discussed).
> 
> But it's all out of scope until after Swift 4 comes out, because none of this 
> affects ABI or source-code compatibility.
> 
> - Dave Sweeris
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Revisiting SE-0110

2017-05-29 Thread Robert Bennett via swift-evolution
I think the goal of SE 0110 and to a lesser extent 0066 was to disallow this 
level of intelligence in the compiler. While technically feasible, it's not 
desirable to overload parentheses in this manner.

> On May 29, 2017, at 3:41 PM, Nevin Brackett-Rozinsky via swift-evolution 
>  wrote:
> 
>> On Mon, May 29, 2017 at 3:18 PM, Vladimir.S  wrote:
>>> On 29.05.2017 21:08, Nevin Brackett-Rozinsky wrote:
>>> barTuple{ (x, y) in }   // valid, destructuring one tuple
>>> barTuple{ ((x, y)) in } // valid, destructuring one tuple with optional 
>>> parentheses
>> 
>> Here is the problem for me. According to SE-0066 closure declared as {(x,y) 
>> in} should be of type (Int,Int)->() and not ((Int,Int))->().
>> Why do you want to be able to pass wrong function/closure type into barTuple?
> 
>  I don’t.
> 
> I want the compile to infer from context whether “{ (x, y) in }” is of type 
> “(_, _) -> _” with the optional parentheses included, or of type “((_, _)) -> 
> _” with the optional parentheses elided. This is similar to how we use 
> context to determine whether “1” is of type Int or Double or something else 
> entirely.
> 
> If a closure appears in a context where it can only accept a tuple, such as 
> mapping a dictionary, then obviously its type should have a tuple parameter. 
> If a closure appears in a context where it can only accept two arguments, 
> then obviously its type should have two parameters.
> 
> I want the compiler to figure out, when possible from context, whether the 
> optional parentheses were included, so it “just works” for developers.
> 
> Nevin
> 
> ___
> swift-evolution mailing list
> swift-evolution@swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Revisiting SE-0110

2017-05-29 Thread Robert Bennett via swift-evolution
> Well, from my point of view closure deserves some special syntax and rules.

Not sure I agree with that. Closures are just anonymous functions and so IMO 
their syntax should differ from function syntax as little as possible while 
retaining clarity. A named function call is written f(x, y) or g((x, y)). 
Immediately you know which has two arguments and which has a 2-tuple as its 
sole argument. I'm suggesting that for closures we merely transplant this 
syntax.

The only question (for me) is whether to include everything including the outer 
parentheses, or just everything between the parentheses. I would prefer to 
include everything including the outer parentheses because of the additional 
clarity (and IMO aesthetic quality) of making this syntax parallel the syntax 
enforced in SE 0066 and 0110:
let f1: (Int, Int) -> Double = { (x, y) in ...}
let f2: ((Int, Int)) -> Double = { ((x, y)) in ...}

The closures mirror their declarations, which (if implemented) would make it 
clear that the closure preambles are correct and will work as expected. It's 
just one fewer thing to have to think about.

> On May 29, 2017, at 2:42 PM, Vladimir.S  wrote:
> 
> Well, from my point of view closure deserves some special syntax and rules.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] Revisiting SE-0110

2017-05-29 Thread Robert Bennett via swift-evolution
The word you're looking for is inconvenient 

If we allow dropping parentheses for tuples then we should disallow the outer 
parentheses to avoid ambiguity between multi-argument closures and closures 
taking a single tuple as their argument. Then, a closure taking multiple 
arguments would have to be written as "x, y in" and a closure taking a tuple as 
"(x, y) in". I'm ok with this too. I just want to make sure whatever solution 
we come up with adheres to the goal of SE-0110, which is to clearly separate 
functions taking multiple arguments from functions taking a tuple. For clarity, 
whatever solution we come up with should wrap the arguments within a tuple in 
an extra pair of parentheses. So for a multi-argument and single-tuple closure, 
respectively, either "x, y in" and "(x, y) in", or "(x, y) in" and "((x, y)) 
in".

> On May 29, 2017, at 1:32 PM, Vladimir.S via swift-evolution 
>  wrote:
> 
>> On 29.05.2017 18:26, Nevin Brackett-Rozinsky via swift-evolution wrote:
>> On Sun, May 28, 2017 at 7:04 PM, John McCall via swift-evolution 
>> > wrote:
>>We need to add back tuple destructuring in closure parameter lists 
>> because this
>>is a serious usability regression.  If we're reluctant to just "do the 
>> right
>>thing" to handle the ambiguity of (a,b), we should at least allow it via
>>unambiguous syntax like ((a,b)).  I do think that we should just "do the 
>> right
>>thing", however, with my biggest concern being whether there's any 
>> reasonable way
>>to achieve that in 4.0.
>>John.
>> I agree with John, the best thing for actually using Swift is to allow tuple 
>> destructuring here, and the outermost parentheses (around the entire 
>> parameter list of a closure) should continue to be optional. Requiring 
>> double-parens would seem unnecessarily and arbitrarily…whatever the opposite 
>> of “convenient” is.
>> Nevin
> 
> If I understand correctly, correct me if I'm wrong, after *full* 
> implementation of SE-0066, the function with two parameters should have 
> different type than function with one tuple parameter:
> 
> I.e.
> typealias FuncParams = (Int, Int)->()
> typealias FuncTuple = ((Int, Int))->()
> 
> print(FuncParams.self) // should be (Int, Int)->()
> print(FuncTuple.self) // should be ((Int, Int))->()
> 
> So, if we have
> 
> func barParams(_ f: FuncParams) {
>f(1,2)
> }
> 
> func barTuple(_ f: FuncTuple) {
>f((1,2))
> }
> 
> and
> 
> func fooWithParams(_ x: Int,  _ y: Int) {  }
> func fooWithTuple(_ tuple: (Int, Int)) {  }
> 
> .. we should not be able to call
> 
> barParams(fooWithTuple) // should be error: incompatible types
> barTuple(fooWithParams) // should be error: incompatible types
> 
> 
> If so, are you suggesting that this code should still be valid?
> 
> barParams({tuple in}) // ?
> barTuple({x,y in}) // ?
> 
> 
> Will {x,y in} closure has ((Int, Int))->() type in this case?
> And if {tuple in} should be of type (Int,Int)->() ?
> 
> If I'm not missing something, the only reasonable solution here is follow the 
> SE-0066 rules for function types and allow special syntax ((x,y)) to 
> deconstruct tuple parts in closure argument list, and such closure will have 
> type ((Int,Int))->() as expected. So we'll have:
> 
> barTuple({((x,y)) in ... })
> 
> 
>> ___
>> 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] Revisiting SE-0110

2017-05-28 Thread Robert Bennett via swift-evolution
Er, I think I misunderstood the proposal and discussion and prior work (e.g. 
SE-0066 
<https://github.com/apple/swift-evolution/blob/master/proposals/0066-standardize-function-type-syntax.md>)
 and so my contribution to this discussion was not great. Here are my revised 
thoughts in light of a reread of the relevant material. Below is an outline of 
what I think closure signatures should look like. (For all of the below 
examples, the ability to explicitly include return type in the closure 
"preamble" is assumed.)

0) If a closure takes no arguments, acceptable "preambles" should be: omitting 
named variables and the "in" keyword, "() in", or "Void in".

1) If a closure takes one argument, acceptable preambles should be: "(arg) in" 
or "(_) in".

2) If a closure takes at least two arguments, acceptable preambles should be, 
e.g., "(x, y) in", with every spot in the tuple replaceable by an underscore.

3) If a closure takes at least one argument, "_ in" means that *all* arguments 
are ignored, regardless of how many there are. For a single-argument closure, 
"_ in" is shorthand for "(_) in". For multiple-argument closures, it is 
shorthand for "(_, _, …, _) in". "_ in" is not allowed for nullary closures.

4) Tuple unpacking can be achieved by replacing the variables inside the outer 
parentheses with tuples. For a Dictionary, whose Element is of type (key: Key, 
value: Value), this means writing "((key, value)) in", i.e., replacing the 
"arg" in "(arg) in" with "(key, value)". For a Dictionary<String, (Int, 
Double)>, you could do "((s, (i, d))) in". If and only if the tuple in question 
had named positions, they would also be allowed in the closure preamble. So for 
a Dictionary<String, (length: Int, score: Double)> you could write "((key: s, 
(length: i, score: d))) in". The rules for tuple position labels would be the 
same as for regular tuples (whatever those may be; I can never keep track of 
exactly what is (dis)allowed).

5) The only point I foresee sparking much debate: there should be no 
permissible shorthands/syntactic sugar except for those outlined above. In 
particular, parentheses should be required for all closures taking a nonzero 
number of arguments.

Rationale: Allowing the shorthand "arg in" suggests that when arg is a tuple, 
"(x, y) in" should accomplish the unpacking, which is incorrect. Allowing the 
shorthand "x, y in" suggests that for single-argument closures, "arg in" should 
be allowed, which (according to this) would be incorrect. I don't like the idea 
of special-casing the syntactic sugar and allowing users to drop the outer 
parentheses as long as the closure does not take one argument that is a tuple 
(I think that's the only case the compiler would be unable to resolve). Also, I 
would imagine the migration path to enforce parentheses around arguments is 
trivial to implement.

Requiring parentheses also finishes the job started by SE-0066. In fact it more 
or less perfectly mirrors the proposed solution 
<https://github.com/apple/swift-evolution/blob/master/proposals/0066-standardize-function-type-syntax.md#proposed-solution>
 to the problem of function types.. The only difference here is that we're 
talking about argument lists, not function types, but why pass up an 
opportunity to unify the two?

—
Robert Bennett


> On May 27, 2017, at 8:23 AM, Gwendal Roué <gwendal.r...@gmail.com> wrote:
> 
>> Le 27 mai 2017 à 14:20, Gwendal Roué <gwendal.r...@gmail.com 
>> <mailto:gwendal.r...@gmail.com>> a écrit :
>> 
>>> Le 26 mai 2017 à 21:35, Robert Bennett via swift-evolution 
>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> a écrit :
>>> 
>>> On the contrary I think the solution can absolutely be to break other code. 
>> 
>> You can break whatever you want.
>> 
>> But whatever the solution you come up with, remember that SE-0110 currently 
>> *degrades* the quality of code written by Swift programmers. It can be 
>> argued that SE-0110 is a blatant *regression*. Maybe not as bad as the 
>> initial introduction of fileprivate, but something which is pretty bad, 
>> though.
>> 
>> References:
>> - 
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170522/036808.html
>>  
>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170522/036808.html>
>> - 
>> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170522/036814.html
>>  
>> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170522/036814.html>
> One more link, about the loss of single-lign closures induced by SE-0110: 
> https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170522/036792.html
>  
> <https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170522/036792.html>
> 
> Gwendal

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


Re: [swift-evolution] Revisiting SE-0110

2017-05-26 Thread Robert Bennett via swift-evolution
On the contrary I think the solution can absolutely be to break other code. 
Allowing no parentheses is not a very useful shorthand -- it only saves two 
characters -- and with SE-0110 actually obscures the logic. Always requiring 
parentheses makes it clear that "{ (arg) in ..." can be replaced with "{ ((key, 
value)) in ..." when arg is a 2-tuple; the outer parentheses denote an argument 
list, and anything inside them is the argument, consistent with other parts of 
the language. Allowing "{ arg in ..." but not "{ (key, value) in ..." is sure 
to leave some people scratching their heads because "{ arg in ..." suggests 
that it is arguments that are passed to closures (as is the case with 
functions) and not tuples. The correctness of "{ arg in ..." relies too heavily 
on the equivalence between a 1-tuple and a single element, an equivalence that 
does not hold for higher arities.

I'm not *too* strongly wed to this, though. I care much more strongly about 
allowing  "{ ((key, value)) in ..." than prohibiting  "{ arg in ...". I only 
brought up the latter to try to improve the consistency of the language and to 
make clear that  "{ ((key, value)) in ..." is the correct way of achieving the 
old style "{ (key, value) in ..."

> On May 26, 2017, at 2:57 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
> Requiring parentheses in closures like that was discussed during SE-0110 and 
> rejected; the rationale was that it's a useful shorthand, and that the whole 
> closure syntax is wildly different from function declarations: you don't need 
> to write the type of the arguments, and you don't need to write the return 
> value, so why would it make sense to enforce this particular formality?
> 
> At this point, I'd be very much against now requiring it. The whole rationale 
> for revisiting SE-0110 is that it is breaking lots of code, and the solution 
> cannot be to break lots of other code. The double parenthesis syntax or the 
> let syntax for destructuring seem to be fine mitigations, the former because 
> it strictly parallels the change in syntax in SE-0110 where a single tuple 
> argument has two sets of parentheses, and the latter because it's the same 
> destructuring syntax as is used elsewhere for pattern matching.
>> On Fri, May 26, 2017 at 11:45 David Sweeris via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> > On May 26, 2017, at 08:14, Robert Bennett via swift-evolution 
>> > <swift-evolution@swift.org> wrote:
>> >
>> > Alternatively, for maximum consistency we could make "{ arg in ..." 
>> > illegal as well, requiring parentheses around "arg". This would mirror the 
>> > parentheses necessary in e.g., "let f: (Int) -> Int", and there would be 
>> > no confusion as to why " { arg in ..." is legal but not "{ (key, value) in 
>> > ...".
>> 
>> I think I would support that. Until quite recently, I was under the 
>> impression that closures' "inner signatures" were part of that proposal, 
>> anyway.
>> 
>> (Come to think of it... were they? I suppose it could be a bug that the 
>> "old" syntax is still accepted here.)
>> 
>> - Dave Sweeris
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Revisiting SE-0110

2017-05-26 Thread Robert Bennett via swift-evolution
Alternatively, for maximum consistency we could make "{ arg in ..." illegal as 
well, requiring parentheses around "arg". This would mirror the parentheses 
necessary in e.g., "let f: (Int) -> Int", and there would be no confusion as to 
why " { arg in ..." is legal but not "{ (key, value) in ...".
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] Revisiting SE-0110

2017-05-26 Thread Robert Bennett via swift-evolution
I've tried to follow this thread, but forgive me if I'm suggesting something 
that's already been mentioned. Could we allow tuple destructuring by wrapping 
the inner tuple in parentheses in the closure?

var d = [String: Int]()
// Do stuff with d

d.forEach { (key, value) in ... } // Illegal; argument to closure is a 2-tuple, 
not two arguments

d.forEach { (arg) in // Works, but ugly
let key = arg.key
let value = arg.value
...
}

Now, based on the above, I'm proposing that this should work:

d.forEach { ((key, value)) in ... } 

Since arg == (key, value), "(arg) in" should be equivalent to "((key, value)) 
in". In light of this, "{ arg in ..." would merely be syntactic sugar for "{ 
(arg) in ...", since 1-tuples don't actually exist (`let f: (Int) = 1; 
print(f.0)` doesn't compile, and `let f: ((Int, Int)) = (1,2); print(f.0)` 
prints `1`, not `(1, 2)`).
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-04-22 Thread Robert Bennett via swift-evolution
I'm not sure how we could implement breaking lines with \ for single line 
strings. Either indentation has to be stripped from the broken line, or the 
line must not be indented in which case nothing has been gained because soft 
wrap would accomplish the same thing. (Is there an option I'm missing?)

Now that we have """strings""", we could simply say: if you want to break a 
string over multiple lines, use a """string""" as a "string" does not permit 
this.

> On Apr 22, 2017, at 11:12 AM, Xiaodi Wu  wrote:
> 
> On Sat, Apr 22, 2017 at 3:38 AM, Brent Royal-Gordon  
> wrote:
>>> On Apr 21, 2017, at 11:48 AM, Xiaodi Wu via swift-evolution 
>>>  wrote:
>>> 
>>> This goes to my question to David Hart. Isn't this an argument for a 
>>> feature to allow breaking a single-line string literal across multiple 
>>> lines? What makes this a use case for some feature for _multiline_ string 
>>> literals in particular?
>> 
>> Well, if you're breaking a string across several lines, you will want 
>> indentation stripping too. Are you suggesting we should also bring that 
>> feature to single-line string literals with escaped newlines?
> 
> No, I am suggesting that whatever design is used for escaped newlines, if at 
> all possible it should be equally apt for "strings" and """strings""" such 
> that it will not require indentation stripping.
> 
>> 
>> -- 
>> Brent Royal-Gordon
>> Architechies
>> 
> 
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-04-21 Thread Robert Bennett via swift-evolution
It looks like we have different interpretations about what "literal" means (I 
think this may have been brought up in earlier messages in this thread; I don't 
remember the resolution). I interpreted it as meaning the same thing as literal 
in *LiteralConvertible, i.e., a Swift type that is written out in source. 
Multiline string literal would then refer to a multiline "piece of source code 
representing a String". It sounds like you are taking "literal" to mean 
something that *literally* (to the extent possible) represents its data, which 
in the case of String would mean writing out the source code exactly as the 
resulting String will appear. Up until now I think those two interpretations of 
"literal" were equivalent. For no type other than String is the physical layout 
in source related to the underlying data, and prior to this proposal the point 
was moot for String because there was only a single allowable layout (barring 
concatenation with +, which utilizes multiple independent literals).

So, my view of the goal of this proposal is to allow writing a 
StringLiteralType across multiple lines. It appears your view is to allow using 
multiple lines to *literally* represent a String's content.

Again, for editors that indent wrapped lines, disallowing manually breaking 
lines will actually introduce ambiguity into the multiline string, which runs 
counter to the goal of the proposal. Also, from an ideological standpoint I see 
no reason to disallow this feature.

-- Robert

> On Apr 21, 2017, at 2:48 PM, Xiaodi Wu <xiaodi...@gmail.com> wrote:
> 
>> On Fri, Apr 21, 2017 at 1:45 PM, Erica Sadun <er...@ericasadun.com> wrote:
>> 
>>> On Apr 21, 2017, at 12:40 PM, Xiaodi Wu via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>>> On Fri, Apr 21, 2017 at 8:48 AM, Robert Bennett via swift-evolution 
>>>> <swift-evolution@swift.org> wrote:
>>>> Xiaodi, I think one thing you're neglecting is that users may never print 
>>>> out a multiline literal string at all. A string might never be printed or 
>>>> read by a human outside of the code it resides in. In this case it seems 
>>>> perfectly reasonable to ask that it be possible to format the string 
>>>> nicely in the code and disregard how it would actually be printed.
>>> 
>>> Can you give an example of such a use case, where a string is never seen by 
>>> a human but one cannot insert literal newlines and would need elided ones 
>>> instead?
>> 
>> The most common reason is that the code is maintained by a (non-human) 
>> developer, who wants to be able to see and update the code in a readable 
>> form, but that represents a single line that will automatically wrapped by, 
>> for example, a UITextView for (human) consumption. 
> 
> A different scenario from what Robert's describing, but sure. This goes to my 
> question to David Hart. Isn't this an argument for a feature to allow 
> breaking a single-line string literal across multiple lines? What makes this 
> a use case for some feature for _multiline_ string literals in particular?
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-04-21 Thread Robert Bennett via swift-evolution
Xiaodi, I think one thing you're neglecting is that users may never print out a 
multiline literal string at all. A string might never be printed or read by a 
human outside of the code it resides in. In this case it seems perfectly 
reasonable to ask that it be possible to format the string nicely in the code 
and disregard how it would actually be printed.

Even if we intended to print every string we used, I don't agree that a 
string's representation in code should be coupled to its appearance when 
printed. That seems like a needless restriction to impose on the language. The 
whole point of multiline strings is to be able to visually lay out strings as 
desired, independent of the editor. Allowing manual line breaks without 
introducing a newline is one more step toward completing this goal.

To respond to your specific question as to why soft wrap is insufficient: it 
either looks bad because the wrapped text is unindented, or it introduces 
ambiguity by indenting the wrapped text (is that a wrapped line or two separate 
lines?). As Adrian Zubarev pointed out, we wouldn't need multiline string 
literals at all if we were content with manually inserting "\n" in multline 
strings and living with the soft wrapping. Evidently we are not content with 
that, so neither should we be content with having no way to break up long lines 
containing no newline character.

Finally, I see no reason why we should be fighting against this. It only makes 
multiline strings more capable. If you don't want to use manual wrapping of 
lines, you don't have to.

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


[swift-evolution] [Pitch] Adding safety to arrays

2017-04-13 Thread Robert Bennett via swift-evolution
We definitely should not alter the default subscript behavior of Array. 
Perhaps, it might be worthwhile to add a method `element(atIndex: Index) -> 
Element?` or some such method.

It's hard to say whether it would be worth it; the desired behavior can be 
achieved with `0..https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [pitch] One-sided Ranges

2017-04-12 Thread Robert Bennett via swift-evolution
+1, very nice proposal. I think there was some discussion about this before, 
glad to see it being fleshed out into a full proposal. My only nitpick is that 
I think feel like the syntax `sequence[i…]` is awkward because `…` implies the 
entirety of a range (1…5 includes 1 and 5 and everything in between), but the 
valid indices of a sequence go from 0 to endIndex, and endIndex cannot be 
included when slicing. That is, `sequence[i…]` is equivalent to 
`sequence[i..

[swift-evolution] [Review] SE-0166: Swift Archival & Serialization

2017-04-07 Thread Robert Bennett via swift-evolution
Review of SE-0166 "Swift Archival & Serialization: 
"https://github.com/apple/swift-evolution/blob/master/proposals/0166-swift-archival-serialization.md
 


This is an amazing proposal. I have one question about the CodingKey protocol, 
though. It feels strange to provide two ways to access keys, String for 
convenience/clarity and Int for performance, and to have those both floating 
around when only at most one will be used by an Encoder. It's very likely I'm 
missing something here (certainly I haven't thought about this as much as the 
authors of the proposal) but would it make more sense to write CodingKey like 
this?

public protocol CodingKey {
associatedtype Key

var value: Key { get }

init?(value: Key)
}

For any enum conforming to CodingKey, the compiler can still generate the 
implementations of those methods using String as Key, although I don't see why 
it would when using Int is more performant. It might also be necessary to have 
a protocol CodingKeyKeyProtocol (yech) to constrain the Key type — 
associatedtype Key: CodingKeyKeyProtocol — to something that can be used as an 
Encoder/Decoder key. It's possible that Hashable is already sufficient for this 
protocol. This would allow more flexible custom types conforming to CodingKey, 
although I'm not sure if that flexibility is needed. I'm also not sure anything 
aside from Int is needed, in which case the associatedtype could be removed and 
Key replaced with Int.



What is your evaluation of the proposal?
+1000

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

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

If you have used other languages or libraries with a similar feature, how do 
you feel that this proposal compares to those?
N/A

How much effort did you put into your review? A glance, a quick reading, or an 
in-depth study?
Read the whole proposal, did my best to understand it but it's a lot to digest.

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


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

2017-04-06 Thread Robert Bennett via swift-evolution
• What is your evaluation of the proposal?

-0.1

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

Yes

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

I don't think so. While Python's way of doing multiline strings may work for 
Python, I don't think it's an aesthetic fit for Swift, both because of the 
somewhat nebulous treatment of newlines and the magical-feeling indentation. 
Magic is a core component of Python, but has no place in Swift.

The alternative, continuation quotes, is my preferred solution to this problem. 
However I think it would be improved if lines began with a single quote or pipe 
or some other character, basically anything other than double quotes.

Advantages of continuation characters are that it is immediately clear how much 
leading whitespace a line actually has and that the string's value is 
insensitive to the indentation of the individual lines. The second point will 
be very useful when copying and pasting multiline strings, as the value of the 
string cannot change unless whitespace is explicitly inserted after the leading 
character. How many times have we copy-pasted code in Python, only to be stung 
by improper indentation of the pasted code? With a leading character on 
continuation lines, you can highlight and auto-indent — that's the only kind of 
magic that Swift should support.

If we want to make copying and pasting text from elsewhere (e.g., SQL queries) 
simple, then the compiler can provide a fix-it for multiline strings lacking 
continuation characters, offering to place the continuation character at the 
start of each line at the position determined by the start of the least 
indented offending line.


However, if we decide not to go with continuation quotes, then I largely agree 
with what Haravikk said here: 
https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20170403/035188.html


• If you have used other languages or libraries with a similar feature, how do 
you feel that this proposal compares to those?

I don't like stealing from Python because Swift's and Python's styles are very 
different. Swift should steer clear of Python's magic.

Aside from Python, no.

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

A quick read, and followed the discussion.


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


[swift-evolution] multi-line string literals

2017-04-03 Thread Robert Bennett via swift-evolution
To throw another idea into the mix: the string surrounded with double quotes, 
each line beginning and ending with a single quote.

let foo = "This is my '
'multi line string '
'with lots of spaces at'
'the end of the above line '
'and more at the start of '
'   this line."


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


[swift-evolution] [Pitch] Add an all algorithm to Sequence

2017-04-01 Thread Robert Bennett via swift-evolution
It figures, the hardest thing to pick is the name of this function…

I like forAll the best so far, but I worry that it sounds too much like forEach 
and would be confusing.

What does everyone think of withoutException? nums.withoutException(isEven) and 
nums.withoutException { isEven($0) } make their purpose clear, and even make 
clear what happens for an empty Collection.

Other options that come to mind that I am less enthusiastic about:

nums.every(satisfies: isEven) / nums.every { isEven($0) }
nums.entirely(isEven) / nums.entirely { isEven($0) }
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Add an all algorithm to Sequence

2017-03-31 Thread Robert Bennett via swift-evolution
That's a good point, but now you've got me wondering whether *those* overloads 
are necessary either :/

I suppose one reason overloads make more sense to me in the case of index and 
contains is because those two operations are in fact frequently used to look 
for a particular element by its value, so the overloads are truly convenient 
(if not strictly necessary). Those operations are also common in other 
languages -- some languages don't even have an index(where:), instead opting to 
search for true in the result of lazily mapping the predicate over the array. 
There is some value to not eschewing convention there.

However, I think all(equal:) *is* an unnecessary convenience because I don't 
think that it is a common operation to check that an array only contains a 
single value (arr.all(equal: 9)? Really? Why would we have an array of all 
9's?), except when checking that a Boolean array is all true or all false. But 
in this case one likely could have used the all(where:) version on another, 
non-Boolean array in the first place. I can't think of an instance where I 
would store a Boolean array for its own sake; Boolean arrays usually represent 
a condition on some array that we *really* care about. In the event that 
someone is using a "genuine" Boolean array, arr.all(equal: true) is no nicer 
than arr.all { $0 }, so we might as well keep the namespace a bit cleaner and 
go with just all(where:).

> On Mar 31, 2017, at 8:11 PM, Ben Cohen <ben_co...@apple.com> wrote:
> 
> 
>> On Mar 31, 2017, at 4:20 PM, Robert Bennett via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> Sorry, despite the curt tone of my initial post, I think this is overall a 
>> great idea. Ben, thanks for drafting the proposal.
>> 
> 
> No worries!
> 
>>> On Mar 31, 2017, at 6:12 PM, Ricardo Parada <rpar...@mac.com> wrote:
>>> 
>>> I agree. 
>>> 
>>>> On Mar 31, 2017, at 5:32 PM, Robert Bennett via swift-evolution 
>>>> <swift-evolution@swift.org> wrote:
>>>> 
>>>> I'm don't think we need all(equal:).
>>>> 1) For a host of reasons, having a single signature for a function name is 
>>>> better than having multiple signatures when the single signature is 
>>>> capable enough.
>>>> 2) A list containing a single distinct element is not a special enough 
>>>> case to check for to warrant its own function signature.
>>>> 
>>>> all(equal:) can be replicated easily enough with nums.all { $0 == 9 }. 
>>>> Unlike all(equals:), this is extendible to non-Equatable types with 
>>>> equatable members.
> 
> It is a pretty well-established practice in the standard library at this 
> point to overload like this, with a version relying on protocol conformance, 
> and a more general version that takes a closure and doesn't. So sort() relies 
> on Comparable, but sort(by:) doesn’t, contains(_:) and index(of:) rely on 
> Equatable, but contains(where:) and index(where:) are more general versions 
> that take a closure. There are several other similar examples. This proposal 
> follows along similar lines.
> 
>>>> ___
>>>> 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] Add an all algorithm to Sequence

2017-03-31 Thread Robert Bennett via swift-evolution
Sorry, despite the curt tone of my initial post, I think this is overall a 
great idea. Ben, thanks for drafting the proposal.

> On Mar 31, 2017, at 6:12 PM, Ricardo Parada <rpar...@mac.com> wrote:
> 
> I agree. 
> 
>> On Mar 31, 2017, at 5:32 PM, Robert Bennett via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> I'm don't think we need all(equal:).
>> 1) For a host of reasons, having a single signature for a function name is 
>> better than having multiple signatures when the single signature is capable 
>> enough.
>> 2) A list containing a single distinct element is not a special enough case 
>> to check for to warrant its own function signature.
>> 
>> all(equal:) can be replicated easily enough with nums.all { $0 == 9 }. 
>> Unlike all(equals:), this is extendible to non-Equatable types with 
>> equatable members.
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [Pitch] Add an all algorithm to Sequence

2017-03-31 Thread Robert Bennett via swift-evolution
I'm don't think we need all(equal:).
1) For a host of reasons, having a single signature for a function name is 
better than having multiple signatures when the single signature is capable 
enough.
2) A list containing a single distinct element is not a special enough case to 
check for to warrant its own function signature.

all(equal:) can be replicated easily enough with nums.all { $0 == 9 }. Unlike 
all(equals:), this is extendible to non-Equatable types with equatable members.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [Pitch] String revision proposal #1

2017-03-30 Thread Robert Bennett via swift-evolution
Adrian,

I think there are a few competing claims here.

1) Substring is a term of art used universally throughout computing, and 
camel-casing it would run counter to that.
2) While subsequence is a word, its  precise mathematical meaning differs from 
what it means in Swift. In Swift a SubSequence contains consecutive elements of 
a sequence, whereas in math a subsequence may contain any subset of the 
elements, ordered correctly. Hence Subsequence would be technically incorrect 
(not a big issue IMO).
3) We want Sub[sS]tring and Sub[sS]equence to have the same capitalization.

I'd prefer ignoring 2 and satisfying 1 and 3, since there's no reason Swift's 
names must exactly coincide with mathematical objects with the same name (for 
instance, mathematical sets may contain anything at all, including themselves). 
In addition, the prefix "Sub" does not usually (ever?) produce a Sequence with 
wholly different mechanics, as do "Enumeration", "Zip2", etc. -- the 
Subsequence really belongs to the owning Sequence. So my vote is for Substring 
and Subsequence.

As for why not StringSlice... Substring is certainly a more familiar word. That 
said, StringSlice would make it clearer that the slice is a view into a String 
and is meant for temporary use only, which Substring might not convey. If we 
choose StringSlice, I see no reason to change SubSequence to Subsequence.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-03-16 Thread Robert Bennett via swift-evolution
Agreed, I'm fine with a way of achieving this without T != Type. I suppose I 
should have made the subject "Fix Swift's type checker in this particular case".

I still have trouble figuring out *how* it can correctly handle ambiguity in 
protocol extensions but be unable to in a "true" (constructible) type 
extension. Does this warrant a bug report of some kind?

> On Mar 16, 2017, at 11:27 PM, Slava Pestov <spes...@apple.com> wrote:
> 
> Overload resolution has a lot of heuristics, but it’s not magic. It simply 
> doesn’t know how to handle this case.
> 
> I’d be in favor of consolidating and simplifying the overload resolution 
> rules, with the goal of disambiguating common cases that are currently 
> ambiguous. We might even be able to do that without breaking too much user 
> code, since a lot of the rules there were put in place to handle specific 
> situations that came up in the standard library.
> 
> However adding more heuristics to handle specific examples is a -1 from me. 
> :-)
> 
> Slava
> 
>> On Mar 16, 2017, at 7:38 PM, Jaden Geller via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> I would’ve expected overload resolution to pick the “more specific” one in 
>> this case without needing any additional constraints… 樂
>> 
>>> On Mar 16, 2017, at 6:40 PM, Robert Bennett via swift-evolution 
>>> <swift-evolution@swift.org> wrote:
>>> 
>>> Hello,
>>> 
>>> This discussion sort of fizzled out when the topic was first introduced. 
>>> Joe Groff had asked the following:
>>> 
>>>> Do you have a concrete example where you need this? It'd be good to know 
>>>> whether the types are ambiguous due to type checker bugs, or whether 
>>>> there's a principle by which they could be naturally ordered.
>>> 
>>> There is an example of this ordering that I stumbled upon recently. Suppose 
>>> I wish to extend `Array` with a `uniques()` function that returns an array 
>>> containing the unique elements of `self`. For performance reasons, I would 
>>> first write a method for arrays with Hashable elements, so that I could 
>>> check for uniqueness in constant time per element.
>>> 
>>> extension Array where Element: Hashable {
>>> func uniques() -> [Element] {
>>> var seen: Set = []
>>> var uniq: [Element] = []
>>> 
>>> for e in self {
>>> if !seen.contains(e) {
>>> seen.insert(e)
>>> uniq.append(e)
>>> }
>>> }
>>> 
>>> return uniq
>>> }
>>> }
>>> 
>>> However I would still like to have a `uniques()` method for arrays whose 
>>> elements are merely Equatable, and I'm willing to take the performance cost 
>>> of O(n) lookup per element.
>>> 
>>> extension Array where Element: Equatable {
>>> func uniques() -> [Element] {
>>> var uniq: [Element] = []
>>> 
>>> for e in self {
>>> if !uniq.contains(e) {
>>> uniq.append(e)
>>> }
>>> }
>>> 
>>> return uniq
>>> }
>>> }
>>> 
>>> However, there is a problem, which is that elements that are Hashable are 
>>> also Equatable, and so there is ambiguity when calling this method:
>>> 
>>> // error: ambiguous use of 'uniques()'
>>> print([1,2,3,1,2,4,5,1,2,3,4,5].uniques())
>>> 
>>> 
>>> If I could add `Element != Hashable` to the second extension, there would 
>>> be no ambiguity.
>>> 
>>> FWIW replacing Array with Collection and Element with Iterator.Element 
>>> fixes the error. The first extension (the one for Hashables) is called. I'm 
>>> not sure why it is ambiguous in one case and not the other.
>>> 
>>> ___
>>> swift-evolution mailing list
>>> swift-evolution@swift.org
>>> https://lists.swift.org/mailman/listinfo/swift-evolution
>> 
>> ___
>> swift-evolution mailing list
>> swift-evolution@swift.org
>> https://lists.swift.org/mailman/listinfo/swift-evolution
> 

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


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

2017-03-16 Thread Robert Bennett via swift-evolution
Hello,

This discussion sort of fizzled out when the topic was first introduced. Joe 
Groff had asked the following:

> Do you have a concrete example where you need this? It'd be good to know 
> whether the types are ambiguous due to type checker bugs, or whether there's 
> a principle by which they could be naturally ordered.

There is an example of this ordering that I stumbled upon recently. Suppose I 
wish to extend `Array` with a `uniques()` function that returns an array 
containing the unique elements of `self`. For performance reasons, I would 
first write a method for arrays with Hashable elements, so that I could check 
for uniqueness in constant time per element.

extension Array where Element: Hashable {
func uniques() -> [Element] {
var seen: Set = []
var uniq: [Element] = []

for e in self {
if !seen.contains(e) {
seen.insert(e)
uniq.append(e)
}
}

return uniq
}
}

However I would still like to have a `uniques()` method for arrays whose 
elements are merely Equatable, and I'm willing to take the performance cost of 
O(n) lookup per element.

extension Array where Element: Equatable {
func uniques() -> [Element] {
var uniq: [Element] = []

for e in self {
if !uniq.contains(e) {
uniq.append(e)
}
}

return uniq
}
}

However, there is a problem, which is that elements that are Hashable are also 
Equatable, and so there is ambiguity when calling this method:

// error: ambiguous use of 'uniques()'
print([1,2,3,1,2,4,5,1,2,3,4,5].uniques())


If I could add `Element != Hashable` to the second extension, there would be no 
ambiguity.

FWIW replacing Array with Collection and Element with Iterator.Element fixes 
the error. The first extension (the one for Hashables) is called. I'm not sure 
why it is ambiguous in one case and not the other.

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


Re: [swift-evolution] Add a `clamp` function to Algorithm.swift

2017-03-10 Thread Robert Bennett via swift-evolution
I can't argue with that. I guess I was really only opposed to using the 
half-open range for Double and other theoretically non-discrete types, for the 
reasons I listed. I have no objections to clamping with a half-open Integer 
range; I just hadn't considered further restricting the Bound of the Range in 
use. arr[idx.clamped(to: arr.indices)] looks amazing.

> On Mar 11, 2017, at 12:29 AM, Jaden Geller <jaden.gel...@gmail.com> wrote:
> 
>> 
>> On Mar 10, 2017, at 8:04 PM, Robert Bennett via swift-evolution 
>> <swift-evolution@swift.org> wrote:
>> 
>> I really like this proposal, and think that it does have a place in Swift 4. 
>> Two quick notes in light of the discussion: first, I think it should be 
>> called clamped, not clamp; second, I think it should only take ClosedRange. 
>> More on those later, but first I'll respond to the six questions raised by 
>> Xiaodi.
>> 
>>> 1. Is it truly a frequent operation?
>> I think so. I've certainly wished for it on an occasion or two. I settle for 
>> min(upper, max(lower, value)).
>> 
>>> 2. Is the helper more readable? Is the composed equivalent obvious at a 
>>> glance?
>> Definitely (or I imagine it will be once we get the details figured out). 
>> There are two equivalent forms of the min-max version, the other being 
>> max(lower, min(upper, value)), not to mention the commutativity of the 
>> arguments themselves. I am under the impression that Swift is not a big fan 
>> of having multiple equivalent ways to do the same thing — that was part of 
>> the reason ++ was nixed. value.clamp(to: closedRange) is clear and is not 
>> interchangeable with any one thing in the language.
>> 
>>> 3. Does the helper have the flexibility to cover all common cases?
>> I see three cases: value < lower, lower <= value <= upper, and upper < 
>> value. All are covered.
>> 
>>> 4. Is there a correctness trap with the composed equivalent? Is there a 
>>> correctness trap with the helper?
>> I don't think so, if we limit to ClosedRange.
>> 
>>> 5. Is there a performance trap with the composed equivalent? Or with the 
>>> helper?
>> I don't know, is there a significant cost associated to constructing a 
>> ClosedRange solely for the purpose of using its bounds? I would imagine not, 
>> but someone who knows more about Swift can answer.
>> 
>>> 6. Does the helper actually encourage misuse?
>> I don't see how, if we limit its argument to ClosedRange.
>> 
>> 
>> Going back to my earlier points — I think that to keep things in line with 
>> Swift's naming conventions, this function should be called clamped, as it 
>> returns a modified version of the calling object. Alternatively, we could 
>> follow the standard set by other numeric types and provide the non-mutating 
>> clamped and the mutating clamp, like multiplied/multiply for Double.
>> 
>> Finally, I don't think it makes mathematical sense to clamp to a non-closed 
>> range. Refer back to the original definition proposed, `min(upperBound, 
>> max(lowerBound, value))`. ClosedRange was proposed as a convenience for 
>> providing those bounds. This makes sense because a ClosedRange contains its 
>> bounds. Since (mathematical) non-closed ranges don't contain their bounds, 
>> it doesn't make sense to use a non-closed range to provide those bounds.
> 
> I think open ranges should be supported, but not for all `Comparable` types. 
> It would however be reasonable to support it for types with discrete ordered 
> values, all `Integer` types for example. I think we might be able to provide 
> it for `T: Strideable where T.Stride: Integer` even. We definitely cannot 
> provide it for all types though; it’s nonsensical to clamp a real value to a 
> closed range.
> 
>> 
>> Also, the above notwithstanding, I have a hard time figuring out when you 
>> would actually want to constrain a number to be strictly less than an upper 
>> bound, violating Question 1 above. If this behavior were really desired, 
>> better to be explicit and subtract the appropriate delta — 1 for Int, 
>> Double.epsilon (or whatever it's called) for Double. I definitely foresee a 
>> correctness trap with the non-closed Range.
>> 
>> Another reason not to allow half-open ranges is because of their asymmetry. 
>> Half open ranges are only open at their upper end, so you would have the 
>> ability to open-clamp from above but not from below. Seems arbitrary (see 
>> Question 3).
> 
> We already have this asymmetry. Adding a clamp function doesn’t worsen it. 
> Besides, w

[swift-evolution] Add a `clamp` function to Algorithm.swift

2017-03-10 Thread Robert Bennett via swift-evolution
I really like this proposal, and think that it does have a place in Swift 4. 
Two quick notes in light of the discussion: first, I think it should be called 
clamped, not clamp; second, I think it should only take ClosedRange. More on 
those later, but first I'll respond to the six questions raised by Xiaodi.

> 1. Is it truly a frequent operation?
I think so. I've certainly wished for it on an occasion or two. I settle for 
min(upper, max(lower, value)).

> 2. Is the helper more readable? Is the composed equivalent obvious at a 
> glance?
Definitely (or I imagine it will be once we get the details figured out). There 
are two equivalent forms of the min-max version, the other being max(lower, 
min(upper, value)), not to mention the commutativity of the arguments 
themselves. I am under the impression that Swift is not a big fan of having 
multiple equivalent ways to do the same thing — that was part of the reason ++ 
was nixed. value.clamp(to: closedRange) is clear and is not interchangeable 
with any one thing in the language.

> 3. Does the helper have the flexibility to cover all common cases?
I see three cases: value < lower, lower <= value <= upper, and upper < value. 
All are covered.

> 4. Is there a correctness trap with the composed equivalent? Is there a 
> correctness trap with the helper?
I don't think so, if we limit to ClosedRange.

> 5. Is there a performance trap with the composed equivalent? Or with the 
> helper?
I don't know, is there a significant cost associated to constructing a 
ClosedRange solely for the purpose of using its bounds? I would imagine not, 
but someone who knows more about Swift can answer.

> 6. Does the helper actually encourage misuse?
I don't see how, if we limit its argument to ClosedRange.


Going back to my earlier points — I think that to keep things in line with 
Swift's naming conventions, this function should be called clamped, as it 
returns a modified version of the calling object. Alternatively, we could 
follow the standard set by other numeric types and provide the non-mutating 
clamped and the mutating clamp, like multiplied/multiply for Double.

Finally, I don't think it makes mathematical sense to clamp to a non-closed 
range. Refer back to the original definition proposed, `min(upperBound, 
max(lowerBound, value))`. ClosedRange was proposed as a convenience for 
providing those bounds. This makes sense because a ClosedRange contains its 
bounds. Since (mathematical) non-closed ranges don't contain their bounds, it 
doesn't make sense to use a non-closed range to provide those bounds.

Also, the above notwithstanding, I have a hard time figuring out when you would 
actually want to constrain a number to be strictly less than an upper bound, 
violating Question 1 above. If this behavior were really desired, better to be 
explicit and subtract the appropriate delta — 1 for Int, Double.epsilon (or 
whatever it's called) for Double. I definitely foresee a correctness trap with 
the non-closed Range.

Another reason not to allow half-open ranges is because of their asymmetry. 
Half open ranges are only open at their upper end, so you would have the 
ability to open-clamp from above but not from below. Seems arbitrary (see 
Question 3).

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


[swift-evolution] Swift null safety questions

2017-03-06 Thread Robert Bennett via swift-evolution
The explicit-at-definition, implicit-at-call-site force unwrapping of optionals 
can be achieved with this syntax:

func test(name1: String!, name2: String!) {
print(name, name2)
}

// prints 'first second' - does not print 'Optional("second")'
test(name1: "first", name2: Optional("second"))

I think this is about as ergonomic as possible.

I agree with Austin that a force-unwrap error should be fatal. There is 
sufficient syntax in the language to allow the safe handling of optionals that 
we don't need to make the unsafe handling of optionals safe as well. You have 
the opportunity to "catch" a nil value with an if-let or a guard-else; I don't 
see a compelling reason to allow the catching of errors arising from 
circumventing those constructs.___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


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

2017-02-27 Thread Robert Bennett via swift-evolution
I'm also annoyed by this, so I second this proposal.

To give an explicit example of the kind of code that can lead to frustration 
and a desire for "T != Type":

protocol P1 {}

protocol P2 {
// Now, any type conforming to P1 and P2 may not be added to itself
static func +(lhs: Self, rhs: T) -> Self
static func +(lhs: T, rhs: Self) -> Self
}

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

let s1 = S()
let s2 = S()

print(s1 + s2) // ambiguous use of operator '+'


If I understand, this would be the desired capability:

protocol P1 {}

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

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

Some thought would have to be given to how to handle subtype relationships — 
probably you would use the polymorphic type of the object at the call site.
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


Re: [swift-evolution] [Pitch] Allow trailing argument labels

2017-02-24 Thread Robert Bennett via swift-evolution
> Sorry, that turned into a bit of a rant, though hopefully a constructive one. 
> I wasn't directing this at you in particular; I just wanted to properly get 
> those points across.

No worries at all, we're all working towards the same goal here.

While I agree that the current proposals feel heavy, equally heavy is creating 
an entire type, a one-case enum, for the sake of one function. It may fit into 
the current language design but it is not (IMO) nice by any means. I'm also not 
a huge fan of the existing proposals, including my own dollar-sign proposal. 
But I would like to see some version of this added to the language because it 
does feel awkward to have to rearrange the sentence structure of a function to 
fit Swift's syntax. Just as ending a sentence with a preposition is something 
up with which some people won't put, but which is nevertheless useful to avoid 
awkward sentence structure, I'd prefer not to have to rearrange the English 
sentence structure of a sentence to comply with Swift's syntactical rules — I'd 
like to avoid the awkwardness. So I'll throw one more idea out there.

Older versions of Swift used # to indicate "special" behavior regarding 
parameter labels. Since that use has been deprecated, maybe we could resurrect 
# for trailing argument labels — in theory, for any positional argument labels, 
but one step at a time. This would also fit nicely with the current use of 
#selector, since when used for trailing arguments, # would *select* the 
function.

// Define
func adding(_ other: Self) // default behavior
func adding(_ other: Self, #reportingOverflow)) // overflow reported

// Call
x.adding(y)
x.adding(y, #reportingOverflow)

// Selectors
#selector(adding(_:))
#selector(adding(_:, #reportingOverflow))
___
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


[swift-evolution] [Pitch] Allow trailing argument labels

2017-02-24 Thread Robert Bennett via swift-evolution
Hi everyone, this is my first post, hopefully I get the formatting and 
everything right...
> why not just require a leading dot, like an enum, rather than a colon?
> less syntax to learn, and it still eliminates the extra type.
I think this could lead to ambiguity if the trailing argument label was also an 
enum case, and there was a function signature whose last argument type was that 
enum. E.g.,
enum E {
case trailing
}
func foo(_ i: Int, trailing: E) {}
func foo(_ i: Int, trailing) {}

Now, which version of foo gets called by foo(1, .trailing)? It's a contrived 
example but demonstrates a real problem.
Since the dollar sign is so rarely used — correct me if I'm wrong, but its only 
current use is for positional closure arguments — I propose we use it for 
trailing arguments. The fact that it seems out of place in a function context 
makes its intention clear — unlike, say, a colon which definitely "belongs" 
within a function's parentheses, or a period which can go just about anywhere.
The syntax I propose would be the following:
// Define
func foo(_ i: Int, $trailing) {}
// Call
foo(1, $trailing)

It's not exactly pretty, but it's certainly unambiguous and makes the intention 
clear.

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