> On Dec 19, 2015, at 8:52 PM, Kevin Ballard via swift-evolution 
> <[email protected]> wrote:
> 
> On Fri, Dec 18, 2015, at 02:39 PM, Dave Abrahams via swift-evolution wrote:
>>  
>> Yes, we already have facilities to do most of what Python can do here, but 
>> one major problem IMO is that the “language” of slicing is so non-uniform: 
>> we have [a..<b], dropFirst, dropLast, prefix, and suffix.  Introducing “$” 
>> for this purpose could make it all hang together and also eliminate the “why 
>> does it have to be so hard to look at the 2nd character of a string?!” 
>> problem.  That is, use the identifier “$” (yes, that’s an identifier in 
>> Swift) to denote the beginning-or-end of a collection.  Thus,
>>  
>>   c[c.startIndex.advancedBy(3)] =>c[$+3]        // Python: c[3]
>>   c[c.endIndex.advancedBy(-3)] =>c[$-3]        // Python: c[-3]
>>  
>>   c.dropFirst(3)  =>c[$+3...]     // Python: c[3:]
>>   c.dropLast(3) =>c[..<$-3]     // Python: c[:-3]
>>   c.prefix(3) =>c[..<$+3]     // Python: c[:3]
>>   c.suffix(3) => c[$-3...]     // Python: c[-3:]
>>  
>> It even has the nice connotation that, “this might be a little more 
>> expen$ive than plain indexing” (which it might, for non-random-access 
>> collections).  I think the syntax is still a bit heavy, not least because of 
>> “..<“ and “...”, but the direction has potential. 
>>  
>>  I haven’t had the time to really experiment with a design like this; the 
>> community might be able to help by prototyping and using some alternatives.  
>> You can do all of this outside the standard library with extensions.
>  
> Interesting idea.
>  
> One downside is it masks potentially O(N) operations 
> (ForwardIndex.advancedBy()) behind the + operator, which is typically assumed 
> to be an O(1) operation.

Yeah, but the “$” is sufficiently unusual that it doesn’t bother me too much.

> Alos, the $+3 syntax suggests that it requires there to be at least 3 
> elements in the sequence, but prefix()/suffix()/dropFirst/etc. all take 
> maximum counts, so they operate on sequences of fewer elements.

For indexing, $+3 would make that requirement.  For slicing, it wouldn’t.  I’m 
not sure why you say something about the syntax suggests exceeding bounds would 
be an error.

> There's also some confusion with using $ for both start and end. What if I 
> say c[$..<$]? We'd have to infer from position that the first $ is the start 
> and the second $ is the end, but then what about c[$+n..<$+m]? We can't treat 
> the usage of + as meaning "from start" because the argument might be 
> negative. And if we use the overall sign of the operation/argument together, 
> then the expression `$+n` could mean from start or from end, which comes 
> right back to the problem with Python syntax.

There’s a problem with Python syntax?  I’m guessing you mean that c[a:b] can 
have very different interpretations depending on whether a and b are positive 
or negative?

First of all, I should say: that doesn’t really bother me.  The 99.9% use case 
for this operation uses literal constants for the offsets, and I haven’t heard 
of it causing confusion for Python programmers.  That said, if we wanted to 
address it, we could easily require n and m above to be literals, rather than 
Ints (which incidentally guarantees it’s an O(1) operation).  That has upsides 
and downsides of course.
>  
> I think Jacob's idea has some promise though:
>  
> c[c.startIndex.advancedBy(3)] => c[fromStart: 3]
> c[c.endIndex.advancedBy(-3)] => c[fromEnd: 3]

> But naming the slice operations is a little trickier. We could actually just 
> go ahead and re-use the existing method names for those:
>  
> c.dropFirst(3) => c[dropFirst: 3]
> c.dropLast(3) => c[dropLast: 3]
> c.prefix(3) => c[prefix: 3]
> c.suffix(3) => c[suffix: 3]
>  
> That's not so compelling, since we already have the methods, but I suppose it 
> makes sense if you want to try and make all slice-producing methods use 
> subscript syntax (which I have mixed feelings about).

Once we get efficient in-place slice mutation (via slice addressors), it 
becomes a lot more compelling, IMO.  But I still don’t find the naming terribly 
clear, and I don’t love that one needs to combine two subscript operations in 
order to drop the first and last element or take just elements 3..<5.

Even if we need separate symbols for “start” and “end” (e.g. using “$” for both 
might just be too confusing for people in the end, even if it works otherwise), 
I still think a generalized form that allows ranges to be used everywhere for 
slicing is going to be much easier to understand than this hodgepodge of words 
we use today.

> But the [fromStart:] and [fromEnd:] subscripts seem useful.

Yeah… I really want a unified solution that covers slicing as well as offset 
indexing.

-Dave



_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to