[Review] SE-0172: One-sided Ranges


(Douglas Gregor) #1

Hello Swift community,

The review of SE-0172 "One-sided Ranges" begins now and runs through April 23, 2017. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md
Reply text
Other replies
<https://github.com/apple/swift-evolution/pulls#what-goes-into-a-review-1>What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?
Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

-Doug

Review Manager


(David Waite) #2

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md
What is your evaluation of the proposal?

I really like the syntax and functionality. I especially like that it creates a protocol that all the various range types implement.

Comments of varying quality:

1. The following example at the start of the proposal does not compile, due both to index(where:) being inappropriate (I assume index(of:) was wanted?) , and index(where:) returning an optional:
let s = "Hello, World!"
let i = s.index(where: ",")
let greeting = s[s.startIndex..<i]

I assume representing an optional as an input to a one-sided range is not intended - it would add complexity and likely mandate an AnyRangeExpression<T> type-erasing class. It is also more likely desirable for greeting to be nil in this case, rather than being an empty String.

It is probably appropriate instead to change the example. To avoid conditionals, I usually go with this syntax:

let s = "Hello, World!"
let i = s.index(where: ",")
let greeting = i.map { s[s.startIndex..<$0] }

2. More on topic, RangeExpression is a protocol that all ranges implement, but appears to only be defined to be evaluated in the context of a collection and its collection indexes. Are there any other non-collection uses of this, such as intersecting two ranges (see point 5)?

3. As more of a general concern about Indexes and Comparable - RangeExpression has a `contains` method, raised I assume from the existing Range types and based on the Comparable index.

However, is it appropriate to evaluate collection indexes in this way, isolated from the collection itself? Today,types like DictionaryIndex will give arbitrary comparison results for indexes generated from two different dictionaries, but trap when methods like distance(from:to:) are called. This may be a bug in the case of DictionaryIndex, but it is not expected that indexes contain information about the collection they came from (such as Array, indexed by Int)

To ask as a more direct question: is it appropriate that an index may return true from RangeExpression contains, but causes a fatal error when used against the collection the RangeExpression index(es) came from?

4. As an extension to the third point, there appears to be a larger API surface of the Range types which could be exposed, such as overlaps() and clamped(to:). If contains() is appropriate for RangeExpression, would it make sense to include these, as well as possibly changing them to be expressed with RangeExpression arguemnts?

5. As a second extension to the third point, some languages have “creative” ranges which only make sense in the context of a collection. An example would be (from Ruby):

“Hello, World!”[-5...-1] # “World"

where the negative index indicates an a negative distance from the end index.

Ignoring syntax bike shedding for the moment, such an expression could not be represented as a RangeExpression due to the inability to properly implement ‘contains’ in isolation of the collection to resolve proper indexes from these offsets.

There would still be ways to implement such behavior if desired by not having the type be a proper RangeExpression and extending Collection. The question is just meant to be another questioning of the relationship of RangeExpression to standalone ranges and to collections.

6. The proposal states:

The prefix and suffix methods that take an index are currently protocol requirements, but should not be. This proposal will fix that as a side-effect.
and
prefix and suffix will be deprecated in Swift 4 and later removed.

It seems removal of prefix and suffix methods from the Collection protocol is a breaking change in addition to removing prefix/suffix from Collection.

Would it be perhaps more desirable for Swift 4 to make prefix/suffix defined on an extension as well as deprecating them for removal in a later version of Swift? This could be done independent of whether this proposal is fully implemented/ships within Swift 4.

Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?

I think so. It will both create a more powerful collection indexing syntax and eliminate multiple functions on collection in the future. The syntax as well I believe is a good fit for the language.

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

I’ve used ranged subscripts in ruby, and to a lesser degree python. Ruby in particular has more in-line functionality for expressing complex subsequence operations (such as negative integer indexes representing a negative offset from the endIndex).

One fun part is that if RangeExpression is an exposed protocol, third parties can implement such extended functionality independent of the standard library (possibly included later if it works out to be highly used with a clear syntax winner.)

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

In-depth study

-DW

···

On Apr 17, 2017, at 10:40 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:


(Haravikk) #3

What is your evaluation of the proposal?

I like the principle of the proposal, but I have some concerns regarding the operators. In particular I don't like that it relies on prefix/postfix versions of the range operator, I'd prefer it to use the standard binary operator with Void as an argument like so:

func ... <T:Comparable>(lhs:T, rhs:Void) -> PartialRangeFrom<T> { … }
func ... <T:Comparable>(lhs:Void, rhs:T) -> PartialRangeTo<T> { … }

let rangeFrom = 5...()
let rangeTo = ()...5

With a view to having underscore in future as another alias for Void, so we can do the following:

let rangeFrom = 5..._
let rangeTo = _...5

Otherwise I like the basic idea (one-sided ranges) I just feel that the one-sidedness of the range operator should be explicit for safety, to avoid accidentally declaring a one-sided range somewhere that may accept one. This should also leave the ellipsis operators free for use in more specialised cases such as variadic tuples, tuple splatting etc.

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

It's relatively minor (there are workarounds), but I'd say so.

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

Yes, aside from the accident safety mentioned above.

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

Read during discussion and re-read now.

···

On 18 Apr 2017, at 05:40, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:


(Matt Lewin) #4

Proposal Link:
https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md

My reply:
Long-time reader, first time commenter.

I agree the need exists to slice up collections as described in the proposal. I also agree that Swift 3’s solution to this is jarring.

Given the example in the proposal:
let s = "Hello, World!"
let i = s.index(where: ",")
let greeting = s[s.startIndex..<i]
I agree that “s.startIndex” is tiresome to write. I question, though, whether it is harmful to readability.

In contrast, the proposed solution of
// half-open right-handed range
let greeting = s[..<i]
// closed right-handed range
let withComma = s[...i]
// left-handed range (no need for half-open variant)
let location = s[i...]
requires both the code-writer and the code-reader to infer the missing side is the start or end.

As an old Perl and Python hacker, the one-sided slicing example from Python, to me, is the perfect example of how those languages obfuscate in the name of brevity. Don’t get me wrong, I never had an issue with any of that when coding in those languages. The beauty of Swift, though, is that it can generally be read by the unindoctrinated.

Unfortunately, I don’t have a palatable alternative syntax solution. Honestly, I would go with s[s.startIndex..<i] for readability purposes.

I suppose we could do something similar to oldValue and newValue in getters and setters. (e.g., s[start..<i], s[i..<end] or s[first..<i], s[i..<last]) While such a thing still requires the layman to pause to consider where those pseudo-constants came from, because they are explicit they are at least somewhat intuitive.

Thanks for your consideration.

-Matt

···

From my perspective, this obfuscates the language by reducing the ability of the code to be read as English. (One of the goals of Swift design, correct?)

On Apr 18, 2017, at 12:40 AM, Douglas Gregor <dgregor@apple.com> wrote:

Hello Swift community,

The review of SE-0172 "One-sided Ranges" begins now and runs through April 23, 2017. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md
Reply text
Other replies
<https://github.com/apple/swift-evolution/pulls#what-goes-into-a-review-1>What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?
Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

-Doug

Review Manager

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


#5

   - What is your evaluation of the proposal?

Strong +1, especially for the unary operators. They make code clear,

concise, and elegant.

Pattern matching against one-sided ranges looks great, and being able to
use postfix “...” to create a sequence is niche but nifty.

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

Definitely. The excessive verbosity of “startIndex” and “endIndex” is a

drag on readability when subscripting.

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

Replacing a long awkward incantation with a simple and aesthetic

alternative is about as Swifty as it gets!

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

Closest would be Matlab with colons for ranges and the “end” keyword. This

proposal is far superior.

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

Participated the discussion when it came up on-list, and read through the

proposal again now that it’s up for review.

Nevin


(Howard Lovatt) #6

review of SE-0172 "One-sided Ranges"

What is your evaluation of the proposal?

Yes. nice addition

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

Probably. Current solution not terrible but proposal better.

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

Yes. Everyone will get what they do straight away.

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

Yes. Most mathematical languages like Matlab and Mathematica have similar and in those languages I use them extensively.

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

Quick read

-- Howard.

···

On 18 Apr 2017, at 2:40 pm, Douglas Gregor <dgregor@apple.com> wrote:

Hello Swift community,

The review of SE-0172 "One-sided Ranges" begins now and runs through April 23, 2017. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md
Reply text
Other replies
What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?
Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

-Doug

Review Manager

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


#7

  • What is your evaluation of the proposal?

+0.75

"RangeExpression" is an unexpected name. I was expecting "RangeProtocol", as in IteratorProtocol and LazySequenceProtocol.

We need a consistent suffix for protocols that can't be named in -able, -ible, or named with a simple noun because the noun is already used by a concrete type. "-Protocol" should be that prefix: RangeProtocol.

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

Yes. Anyone who has written `s[s.startIndex..<i]` knows that something was wrong.

People who claim that s[..<i] or s[i...] are not legible have a demi-point: I predict that all online tutorials about String will rush on those fancy new operators, and they will percolate in the Swift culture very quickly.

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

Yes. That's a very good use of Swift operators.

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

I love how negative indexes are used in Ruby and Python. I know that this can't apply to Swift because not all indexes are integers. This proposal addresses several use cases provided by those negative indexes.

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

I did evaluate the name of RangeExpression, but not its design.

Thanks for this proposal,
Gwendal Roué

···

Le 18 avr. 2017 à 06:40, Douglas Gregor via swift-evolution <swift-evolution@swift.org> a écrit :

Hello Swift community,

The review of SE-0172 "One-sided Ranges" begins now and runs through April 23, 2017. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md
Reply text
Other replies
What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

-Doug

Review Manager

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


(Matt Whiteside) #8

I do like this proposed one-sided range syntax, but a while back it was pointed out that it might conflict with a candidate syntax for variadic generics. Has anything changed there?

-Matt

···

On Apr 17, 2017, at 21:40, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift community,

The review of SE-0172 "One-sided Ranges" begins now and runs through April 23, 2017. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md
Reply text
Other replies
<https://github.com/apple/swift-evolution/pulls#what-goes-into-a-review-1>What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?
Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

-Doug

Review Manager

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


(Colin Barrett) #9

Most of the proposal looks fine to me. A welcome feature. Eager to see
anyone's ideas for further extension to the range DSL—perhaps this will
spark people's imaginations
http://matt.might.net/articles/parsing-with-derivatives/

My only comment is concern over leaving out ..< It's not the prettiest
operator, true, but in the name of consistency and the "principle of least
surprise" I think it's the right one to use. I'm trying to imagine
explaining this to someone learning Swift—"... means up to and including
(except when it doesn't.)" Sounds like a mini-nightmare to me.

Cheers,
-Colin

···

On Tue, Apr 18, 2017 at 12:40 AM Douglas Gregor via swift-evolution < swift-evolution@swift.org> wrote:

Hello Swift community,

The review of SE-0172 "One-sided Ranges" begins now and runs through April
23, 2017. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md

Reviews are an important part of the Swift evolution process. All reviews
should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution

or, if you would like to keep your feedback private, directly to the
review manager. When replying, please try to keep the proposal link at the
top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md

Reply text

Other replies

<https://github.com/apple/swift-evolution/pulls#what-goes-into-a-review-1>What
goes into a review?

The goal of the review process is to improve the proposal under review
through constructive criticism and, eventually, determine the direction of
Swift. When writing your review, here are some questions you might want to
answer in your review:

   - What is your evaluation of the proposal?
   - Is the problem being addressed significant enough to warrant a
   change to Swift?
   - Does this proposal fit well with the feel and direction of Swift?
   - If you have used other languages or libraries with a similar
   feature, how do you feel that this proposal compares to those?
   - How much effort did you put into your review? A glance, a quick
   reading, or an in-depth study?

More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md

Thank you,

-Doug

Review Manager
_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution


(Haravikk) #10

I mentioned in an earlier reply that my preference would be to retain use of the binary operator and use Void as the open end like so:

func ... <T:Comparable>(lhs:T, rhs:Void) -> PartialRangeFrom<T> { … }
func ... <T:Comparable>(lhs:Void, rhs:T) -> PartialRangeTo<T> { … }

let rangeFrom = 5...()
let rangeTo = ()...5

Would that solve your concern? Ideally we could also push for underscore to become another alias for Void when used in such a context, so we could do:

let rangeFrom = 5..._
let rangeTo = _...5

This to me is a bit more explicit that one end of the range being left open on purpose. I initially considered some kind of other symbol, but I think Void/underscore is suitable enough, underscore especially as it's consistent with other features.

···

On 18 Apr 2017, at 15:29, Matt Lewin via swift-evolution <swift-evolution@swift.org> wrote:

In contrast, the proposed solution of
// half-open right-handed range
let greeting = s[..<i]
// closed right-handed range
let withComma = s[...i]
// left-handed range (no need for half-open variant)
let location = s[i...]
requires both the code-writer and the code-reader to infer the missing side is the start or end.

From my perspective, this obfuscates the language by reducing the ability of the code to be read as English. (One of the goals of Swift design, correct?)


#11

Re: [swift-evolution] [Review] SE-0172: One-sided Ranges

"RangeExpression" is an unexpected name. I was expecting "RangeProtocol", as in IteratorProtocol and LazySequenceProtocol. We need a consistent suffix for protocols that can't be named in -able, -ible, or named with a simple noun because the noun is already used by a concrete type. "-Protocol" should be that prefix: RangeProtocol.

A detailed look at API Design Guidelines [1] shows that this subject is not addressed:

  • Protocols that describe what something is should read as nouns (e.g. `Collection`).
  • Protocols that describe a capability should be named using the suffixes `able`, `ible`, or `ing` (e.g. `Equatable`, `ProgressReporting`).

Nothing is said for "protocols that describe what something but can't be named as nouns", or "protocols that describe a capability but can't be named using the suffixes able, ible, or ing".

For example: the name of the protocol for all ranges discussed with SE-0172 should be addressed by the first rule (because the protocol describes what something is rather than a capability). But that protocol can't be named Range because Range is already taken.

Such a situation comes rather easily:

- in an evolving code base, when a protocol is added on top of an existing type hierarchy which should be preserved (RangeProtocol added on top of Range, ClosedRange, etc.)
- at the birth of a code base, when a protocol coexists with a concrete type which rightfully deserves the noun claimed by the protocol.

IteratorProtocol and LazySequenceProtocol have set a precedent: maybe we should have the API Design Guidelines evolve with a third rule:

+ When a protocol can't be named with a noun, or with an `able`, `ible`, or `ing` suffix, the protocol should be named using the suffix `Protocol` (e.g. `IteratorProtocol`).

What do you think?

Gwendal Roué
[1] https://swift.org/documentation/api-design-guidelines/

···

Le 19 avr. 2017 à 17:23, Gwendal Roué <gwendal.roue@gmail.com> a écrit :


(Douglas Gregor) #12

I do like this proposed one-sided range syntax, but a while back it was pointed out that it might conflict with a candidate syntax for variadic generics. Has anything changed there?

It does conflict with the straw man syntax described in the generics manifesto:

  https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#variadic-generics

but variadic generics are a long way off and the syntax is totally up in the air.

  - Doug

···

On Apr 20, 2017, at 6:36 AM, Matt Whiteside <mwhiteside.dev@gmail.com> wrote:

-Matt

On Apr 17, 2017, at 21:40, Douglas Gregor via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Hello Swift community,

The review of SE-0172 "One-sided Ranges" begins now and runs through April 23, 2017. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md
Reply text
Other replies
<https://github.com/apple/swift-evolution/pulls#what-goes-into-a-review-1>What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?
Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

-Doug

Review Manager

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto:swift-evolution@swift.org>
https://lists.swift.org/mailman/listinfo/swift-evolution


(Matt Lewin) #13

Haravikk-

Retaining the use of the binary operator using Void as the open end, certainly helps with readability. As I said in my initial comments, though, my gut is that these operators obfuscate the language. (i.e., it triggers the uninitiated to refer to the Swift documentation)

With that said, short of going with something akin to s[first..<i] and s[i..<last] , I don’t know how we can make it intuitive. Obviously, the first/last approach is pretty darn verbose, so it doesn’t do anything to address the initial concern about s.startIndex being tiresome to write.

As you point out, underscore does does have a nice consistency within the language. It also kind of looks like “open” to me.

Thanks.

-Matt

···

On Apr 18, 2017, at 4:08 PM, Haravikk <swift-evolution@haravikk.me> wrote:

On 18 Apr 2017, at 15:29, Matt Lewin via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

In contrast, the proposed solution of
// half-open right-handed range
let greeting = s[..<i]
// closed right-handed range
let withComma = s[...i]
// left-handed range (no need for half-open variant)
let location = s[i...]
requires both the code-writer and the code-reader to infer the missing side is the start or end.

From my perspective, this obfuscates the language by reducing the ability of the code to be read as English. (One of the goals of Swift design, correct?)

I mentioned in an earlier reply that my preference would be to retain use of the binary operator and use Void as the open end like so:

func ... <T:Comparable>(lhs:T, rhs:Void) -> PartialRangeFrom<T> { … }
func ... <T:Comparable>(lhs:Void, rhs:T) -> PartialRangeTo<T> { … }

let rangeFrom = 5...()
let rangeTo = ()...5

Would that solve your concern? Ideally we could also push for underscore to become another alias for Void when used in such a context, so we could do:

let rangeFrom = 5..._
let rangeTo = _...5

This to me is a bit more explicit that one end of the range being left open on purpose. I initially considered some kind of other symbol, but I think Void/underscore is suitable enough, underscore especially as it's consistent with other features.


(David Rönnqvist) #14

I seem to recall that something (maybe a WWDC session) mentioned something about protocols that in essence represent a single type would have the Protocol-suffix.

Unfortunately I couldn’t find it (yet?). The closest I’ve found so far is http://asciiwwdc.com/2014/sessions/407 but I’m not sure that was it.

essentially when there's a conflict between a class name and a protocol name, we'll append protocol to the name of the protocol.

David

···

On 19 Apr 2017, at 17:55, Gwendal Roué via swift-evolution <swift-evolution@swift.org> wrote:

Le 19 avr. 2017 à 17:23, Gwendal Roué <gwendal.roue@gmail.com> a écrit :

Re: [swift-evolution] [Review] SE-0172: One-sided Ranges

"RangeExpression" is an unexpected name. I was expecting "RangeProtocol", as in IteratorProtocol and LazySequenceProtocol. We need a consistent suffix for protocols that can't be named in -able, -ible, or named with a simple noun because the noun is already used by a concrete type. "-Protocol" should be that prefix: RangeProtocol.

A detailed look at API Design Guidelines [1] shows that this subject is not addressed:

  • Protocols that describe what something is should read as nouns (e.g. `Collection`).
  • Protocols that describe a capability should be named using the suffixes `able`, `ible`, or `ing` (e.g. `Equatable`, `ProgressReporting`).

Nothing is said for "protocols that describe what something but can't be named as nouns", or "protocols that describe a capability but can't be named using the suffixes able, ible, or ing".

For example: the name of the protocol for all ranges discussed with SE-0172 should be addressed by the first rule (because the protocol describes what something is rather than a capability). But that protocol can't be named Range because Range is already taken.

Such a situation comes rather easily:

- in an evolving code base, when a protocol is added on top of an existing type hierarchy which should be preserved (RangeProtocol added on top of Range, ClosedRange, etc.)
- at the birth of a code base, when a protocol coexists with a concrete type which rightfully deserves the noun claimed by the protocol.

IteratorProtocol and LazySequenceProtocol have set a precedent: maybe we should have the API Design Guidelines evolve with a third rule:

+ When a protocol can't be named with a noun, or with an `able`, `ible`, or `ing` suffix, the protocol should be named using the suffix `Protocol` (e.g. `IteratorProtocol`).

What do you think?

Gwendal Roué
[1] https://swift.org/documentation/api-design-guidelines/

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


(Jon Hull) #15

Just to play devil’s advocate, depending on how the protocol actually works, you could claim it *is* a RangeExpression (that is, it is something that can be turned into a range). That was one of the proposals… I lost track of which one was accepted.

Thanks,
Jon

···

On Apr 19, 2017, at 8:55 AM, Gwendal Roué via swift-evolution <swift-evolution@swift.org> wrote:

Le 19 avr. 2017 à 17:23, Gwendal Roué <gwendal.roue@gmail.com> a écrit :

Re: [swift-evolution] [Review] SE-0172: One-sided Ranges

"RangeExpression" is an unexpected name. I was expecting "RangeProtocol", as in IteratorProtocol and LazySequenceProtocol. We need a consistent suffix for protocols that can't be named in -able, -ible, or named with a simple noun because the noun is already used by a concrete type. "-Protocol" should be that prefix: RangeProtocol.

A detailed look at API Design Guidelines [1] shows that this subject is not addressed:

  • Protocols that describe what something is should read as nouns (e.g. `Collection`).
  • Protocols that describe a capability should be named using the suffixes `able`, `ible`, or `ing` (e.g. `Equatable`, `ProgressReporting`).

Nothing is said for "protocols that describe what something but can't be named as nouns", or "protocols that describe a capability but can't be named using the suffixes able, ible, or ing".

For example: the name of the protocol for all ranges discussed with SE-0172 should be addressed by the first rule (because the protocol describes what something is rather than a capability). But that protocol can't be named Range because Range is already taken.

Such a situation comes rather easily:

- in an evolving code base, when a protocol is added on top of an existing type hierarchy which should be preserved (RangeProtocol added on top of Range, ClosedRange, etc.)
- at the birth of a code base, when a protocol coexists with a concrete type which rightfully deserves the noun claimed by the protocol.

IteratorProtocol and LazySequenceProtocol have set a precedent: maybe we should have the API Design Guidelines evolve with a third rule:

+ When a protocol can't be named with a noun, or with an `able`, `ible`, or `ing` suffix, the protocol should be named using the suffix `Protocol` (e.g. `IteratorProtocol`).

What do you think?

Gwendal Roué
[1] https://swift.org/documentation/api-design-guidelines/

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


(Brent Royal-Gordon) #16

I would add that I expect variadic generics to be used less often than one-sided ranges, and also to be a more complex and advanced feature. Both of these suggest that one-sided ranges deserve the simpler, friendlier syntax.

···

--
Brent Royal-Gordon
Sent from my iPhone

On Apr 20, 2017, at 4:38 PM, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

On Apr 20, 2017, at 6:36 AM, Matt Whiteside <mwhiteside.dev@gmail.com> wrote:

I do like this proposed one-sided range syntax, but a while back it was pointed out that it might conflict with a candidate syntax for variadic generics. Has anything changed there?

It does conflict with the straw man syntax described in the generics manifesto:

  https://github.com/apple/swift/blob/master/docs/GenericsManifesto.md#variadic-generics

but variadic generics are a long way off and the syntax is totally up in the air.

  - Doug

-Matt

On Apr 17, 2017, at 21:40, Douglas Gregor via swift-evolution <swift-evolution@swift.org> wrote:

Hello Swift community,

The review of SE-0172 "One-sided Ranges" begins now and runs through April 23, 2017. The proposal is available here:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md
Reviews are an important part of the Swift evolution process. All reviews should be sent to the swift-evolution mailing list at

https://lists.swift.org/mailman/listinfo/swift-evolution
or, if you would like to keep your feedback private, directly to the review manager. When replying, please try to keep the proposal link at the top of the message:

Proposal link:

https://github.com/apple/swift-evolution/blob/master/proposals/0172-one-sided-ranges.md
Reply text
Other replies
What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

What is your evaluation of the proposal?
Is the problem being addressed significant enough to warrant a change to Swift?
Does this proposal fit well with the feel and direction of Swift?
If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/master/process.md
Thank you,

-Doug

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


(Jordan Rose) #17

That was probably about the ObjC importer, which does this (appends "Protocol") when there's a class and protocol with the same name in the same module. That doesn't necessarily mean it's the right thing to put in the API guidelines, though.

Jordan

···

On Apr 19, 2017, at 10:59, Gmail via swift-evolution <swift-evolution@swift.org> wrote:

I seem to recall that something (maybe a WWDC session) mentioned something about protocols that in essence represent a single type would have the Protocol-suffix.

Unfortunately I couldn’t find it (yet?). The closest I’ve found so far is http://asciiwwdc.com/2014/sessions/407 but I’m not sure that was it.
> essentially when there's a conflict between a class name and a protocol name, we'll append protocol to the name of the protocol.

David

On 19 Apr 2017, at 17:55, Gwendal Roué via swift-evolution <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote:

Le 19 avr. 2017 à 17:23, Gwendal Roué <gwendal.roue@gmail.com <mailto:gwendal.roue@gmail.com>> a écrit :

Re: [swift-evolution] [Review] SE-0172: One-sided Ranges

"RangeExpression" is an unexpected name. I was expecting "RangeProtocol", as in IteratorProtocol and LazySequenceProtocol. We need a consistent suffix for protocols that can't be named in -able, -ible, or named with a simple noun because the noun is already used by a concrete type. "-Protocol" should be that prefix: RangeProtocol.

A detailed look at API Design Guidelines [1] shows that this subject is not addressed:

  • Protocols that describe what something is should read as nouns (e.g. `Collection`).
  • Protocols that describe a capability should be named using the suffixes `able`, `ible`, or `ing` (e.g. `Equatable`, `ProgressReporting`).

Nothing is said for "protocols that describe what something but can't be named as nouns", or "protocols that describe a capability but can't be named using the suffixes able, ible, or ing".

For example: the name of the protocol for all ranges discussed with SE-0172 should be addressed by the first rule (because the protocol describes what something is rather than a capability). But that protocol can't be named Range because Range is already taken.

Such a situation comes rather easily:

- in an evolving code base, when a protocol is added on top of an existing type hierarchy which should be preserved (RangeProtocol added on top of Range, ClosedRange, etc.)
- at the birth of a code base, when a protocol coexists with a concrete type which rightfully deserves the noun claimed by the protocol.

IteratorProtocol and LazySequenceProtocol have set a precedent: maybe we should have the API Design Guidelines evolve with a third rule:

+ When a protocol can't be named with a noun, or with an `able`, `ible`, or `ing` suffix, the protocol should be named using the suffix `Protocol` (e.g. `IteratorProtocol`).

What do you think?

Gwendal Roué
[1] https://swift.org/documentation/api-design-guidelines/

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org <mailto: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


#18

Well, IteratorProtocol, LazySequenceProtocol weren't imported from ObjC.

They set a precedent for the -Protocol suffix.

Now, even if you don't like RangeProtocol, this doesn't make RangeExpression better.

"Expression" and `1...` don't belong to the same level of the language: one is a concept of that belongs to the compiler, when the other is a plain value used in a program:

When a program does `1 + 2`, it both sums two integers, and builds a expression from two other expressions and an operator. Both are true. Yet 1 is of type `Integer`, not `IntegerExpression`.

Currently all types of the standard library belong the program realm, not to the compiler realm. I wish we wouldn't break this practice, and avoid `RangeExpression`.

That's why I suggest `RangeProtocol`. Other options could be `Ranging`, `Bounds`...

Gwendal Roué

···

Le 19 avr. 2017 à 23:35, Jordan Rose <jordan_rose@apple.com> a écrit :

That was probably about the ObjC importer, which does this (appends "Protocol") when there's a class and protocol with the same name in the same module. That doesn't necessarily mean it's the right thing to put in the API guidelines, though.

Jordan

On Apr 19, 2017, at 10:59, Gmail via swift-evolution <swift-evolution@swift.org> wrote:

I seem to recall that something (maybe a WWDC session) mentioned something about protocols that in essence represent a single type would have the Protocol-suffix.

Unfortunately I couldn’t find it (yet?). The closest I’ve found so far is http://asciiwwdc.com/2014/sessions/407 but I’m not sure that was it.
> essentially when there's a conflict between a class name and a protocol name, we'll append protocol to the name of the protocol.

David

On 19 Apr 2017, at 17:55, Gwendal Roué via swift-evolution <swift-evolution@swift.org> wrote:

Le 19 avr. 2017 à 17:23, Gwendal Roué <gwendal.roue@gmail.com> a écrit :

Re: [swift-evolution] [Review] SE-0172: One-sided Ranges

"RangeExpression" is an unexpected name. I was expecting "RangeProtocol", as in IteratorProtocol and LazySequenceProtocol. We need a consistent suffix for protocols that can't be named in -able, -ible, or named with a simple noun because the noun is already used by a concrete type. "-Protocol" should be that prefix: RangeProtocol.

A detailed look at API Design Guidelines [1] shows that this subject is not addressed:

  • Protocols that describe what something is should read as nouns (e.g. `Collection`).
  • Protocols that describe a capability should be named using the suffixes `able`, `ible`, or `ing` (e.g. `Equatable`, `ProgressReporting`).

Nothing is said for "protocols that describe what something but can't be named as nouns", or "protocols that describe a capability but can't be named using the suffixes able, ible, or ing".

For example: the name of the protocol for all ranges discussed with SE-0172 should be addressed by the first rule (because the protocol describes what something is rather than a capability). But that protocol can't be named Range because Range is already taken.

Such a situation comes rather easily:

- in an evolving code base, when a protocol is added on top of an existing type hierarchy which should be preserved (RangeProtocol added on top of Range, ClosedRange, etc.)
- at the birth of a code base, when a protocol coexists with a concrete type which rightfully deserves the noun claimed by the protocol.

IteratorProtocol and LazySequenceProtocol have set a precedent: maybe we should have the API Design Guidelines evolve with a third rule:

+ When a protocol can't be named with a noun, or with an `able`, `ible`, or `ing` suffix, the protocol should be named using the suffix `Protocol` (e.g. `IteratorProtocol`).

What do you think?

Gwendal Roué
[1] https://swift.org/documentation/api-design-guidelines/

_______________________________________________
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


#19

Even in this case, this would be a capability, and the guidelines would then recommend RangeExpressible :slight_smile:

Gwendal

···

Le 21 avr. 2017 à 01:18, Jonathan Hull <jhull@gbis.com> a écrit :

Just to play devil’s advocate, depending on how the protocol actually works, you could claim it *is* a RangeExpression (that is, it is something that can be turned into a range). That was one of the proposals… I lost track of which one was accepted.


(Riley Testut) #20

+1 to the proposal, *especially* the addition of the RangeExpression protocol.

That being said, I agree with the critiques over the chosen name. I also can't remember where exactly, but I do remember at some point hearing that the -Protocol suffix should be added to protocol names if needed to disambiguate them from concrete types (and have followed this convention in my own projects).

While I actually believe taken at face value "RangeExpression" is a better name than "RangeProtocol", I believe RangeProtocol is better overall as it is more consistent with the naming conventions. (As an aside, I much preferred Swift 2's "-Type" suffix naming convention for protocols. However, since we're no longer using that, might as well be consistent with other protocol names.)

···

On Apr 20, 2017, at 12:21 AM, Gwendal Roué via swift-evolution <swift-evolution@swift.org> wrote:

Well, IteratorProtocol, LazySequenceProtocol weren't imported from ObjC.

They set a precedent for the -Protocol suffix.

Now, even if you don't like RangeProtocol, this doesn't make RangeExpression better.

"Expression" and `1...` don't belong to the same level of the language: one is a concept of that belongs to the compiler, when the other is a plain value used in a program:

When a program does `1 + 2`, it both sums two integers, and builds a expression from two other expressions and an operator. Both are true. Yet 1 is of type `Integer`, not `IntegerExpression`.

Currently all types of the standard library belong the program realm, not to the compiler realm. I wish we wouldn't break this practice, and avoid `RangeExpression`.

That's why I suggest `RangeProtocol`. Other options could be `Ranging`, `Bounds`...

Gwendal Roué

Le 19 avr. 2017 à 23:35, Jordan Rose <jordan_rose@apple.com> a écrit :

That was probably about the ObjC importer, which does this (appends "Protocol") when there's a class and protocol with the same name in the same module. That doesn't necessarily mean it's the right thing to put in the API guidelines, though.

Jordan

On Apr 19, 2017, at 10:59, Gmail via swift-evolution <swift-evolution@swift.org> wrote:

I seem to recall that something (maybe a WWDC session) mentioned something about protocols that in essence represent a single type would have the Protocol-suffix.

Unfortunately I couldn’t find it (yet?). The closest I’ve found so far is http://asciiwwdc.com/2014/sessions/407 but I’m not sure that was it.
> essentially when there's a conflict between a class name and a protocol name, we'll append protocol to the name of the protocol.

David

On 19 Apr 2017, at 17:55, Gwendal Roué via swift-evolution <swift-evolution@swift.org> wrote:

Le 19 avr. 2017 à 17:23, Gwendal Roué <gwendal.roue@gmail.com> a écrit :

Re: [swift-evolution] [Review] SE-0172: One-sided Ranges

"RangeExpression" is an unexpected name. I was expecting "RangeProtocol", as in IteratorProtocol and LazySequenceProtocol. We need a consistent suffix for protocols that can't be named in -able, -ible, or named with a simple noun because the noun is already used by a concrete type. "-Protocol" should be that prefix: RangeProtocol.

A detailed look at API Design Guidelines [1] shows that this subject is not addressed:

  • Protocols that describe what something is should read as nouns (e.g. `Collection`).
  • Protocols that describe a capability should be named using the suffixes `able`, `ible`, or `ing` (e.g. `Equatable`, `ProgressReporting`).

Nothing is said for "protocols that describe what something but can't be named as nouns", or "protocols that describe a capability but can't be named using the suffixes able, ible, or ing".

For example: the name of the protocol for all ranges discussed with SE-0172 should be addressed by the first rule (because the protocol describes what something is rather than a capability). But that protocol can't be named Range because Range is already taken.

Such a situation comes rather easily:

- in an evolving code base, when a protocol is added on top of an existing type hierarchy which should be preserved (RangeProtocol added on top of Range, ClosedRange, etc.)
- at the birth of a code base, when a protocol coexists with a concrete type which rightfully deserves the noun claimed by the protocol.

IteratorProtocol and LazySequenceProtocol have set a precedent: maybe we should have the API Design Guidelines evolve with a third rule:

+ When a protocol can't be named with a noun, or with an `able`, `ible`, or `ing` suffix, the protocol should be named using the suffix `Protocol` (e.g. `IteratorProtocol`).

What do you think?

Gwendal Roué
[1] https://swift.org/documentation/api-design-guidelines/

_______________________________________________
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