[swift-evolution] Change Request: Make myString.hasPrefix("") and myString.hasSuffix("") return true
Saagar Jha
saagarjha28 at gmail.com
Wed Jul 20 23:32:26 CDT 2016
Sorry, my word choice here is poor. I meant that Swift Strings don’t really match up with character arrays in the usual sense; your “subscript” is O(n). Use a Range instead.
Saagar Jha
> On Jul 20, 2016, at 18:52, Ted F.A. van Gaalen <tedvgiosdev at gmail.com> wrote:
>
>>
>> On 21.07.2016, at 03:15, Saagar Jha <saagarjha28 at gmail.com <mailto:saagarjha28 at gmail.com>> wrote:
>>
>>
>> Saagar Jha
>>
>>
>>
>>> On Jul 20, 2016, at 18:02, Ted F.A. van Gaalen via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>
>>> Hi Nevin,
>>>
>>> extension String
>>> {
>>> var count: Int
>>> {
>>> get
>>> {
>>> return self.characters.count
>>> }
>>> }
>>>
>>> // Sigh... String subscriptors should be already builtin in the String
>>>
>>
>> Swift Strings use grapheme clusters, so subscripting doesn’t really work.
> ?????? sorry Saagar, but it does! try this code in Swift Playground
> I mean that the subscritp functions implemented below could just as well be builtin.
> Ted
>>
>>> subscript (idx: Int) -> String
>>> {
>>> get
>>> {
>>> return self.substringWithRange(
>>> self.startIndex.advancedBy(idx)..<self.startIndex.advancedBy(idx + 1)
>>> )
>>> }
>>> }
>>>
>>> // range subscript [n1..n2] or [n1...n2]
>>>
>>>
>>> subscript (r: Range<Int>) -> String
>>> {
>>> get
>>> {
>>> return self.substringWithRange(
>>> self.startIndex.advancedBy(r.startIndex)..<self.startIndex.advancedBy(r.endIndex) )
>>> }
>>> }
>>>
>>> //////////////////////////////////////////////
>>> func hazPrefix(s: String) -> Bool
>>> {
>>> if self.isEmpty && s.isEmpty // both are empty: match
>>> {
>>> return true
>>> }
>>>
>>> if self.isEmpty || s.isEmpty ||
>>> (s.count > self.count)
>>> {
>>> return false
>>> }
>>>
>>> var match = true
>>>
>>> for i in 0..<s.count
>>> {
>>> if self[i] != s[i]
>>> {
>>> match = false
>>> break
>>> }
>>> }
>>>
>>> return match
>>> }
>>> ///////////////////////////////////////////
>>> } // end String extensions.
>>>
>>>
>>>
>>> let s = "abcdefghijklmnopqrstuvwxyz"
>>> let emptystr = ""
>>> let emptystr2 = ""
>>>
>>> print( s.hazPrefix("abc") ) // true
>>>
>>> print( s.hazPrefix("") ) // false
>>> print( s.hazPrefix("Led Zeppelin.") ) // false
>>> print( emptystr.hazPrefix("Swift") ) // false
>>>
>>> print(emptystr.hazPrefix(emptystr) ) // true
>>>
>>>
>>> Please see further in-line comments below:
>>>
>>> Kind Regards,
>>> Ted
>>>
>>>
>>>> On 21.07.2016, at 00:57, Nevin Brackett-Rozinsky <nevin.brackettrozinsky at gmail.com <mailto:nevin.brackettrozinsky at gmail.com>> wrote:
>>>>
>>>> On Wed, Jul 20, 2016 at 6:32 PM, Ted F.A. van Gaalen via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>> Hi,
>>>>
>>>> Mathematical correct or not:
>>>>
>>>> in case of
>>>> s1.hasPrefix(s2)
>>>> (or any other containment test method)
>>>>
>>>> s1 and s2 are just plain simple instances of String,
>>>> nothing more nothing less.
>>>>
>>>> Which is interpreted by me as:
>>>> “test if String s1 starts with String s2”
>>>>
>>>>
>>>> …which means, “Do the first n characters of s1 match s2, where n is the length of s2?”
>>> Yes,. and of course s1.count <= s2.count.
>>>>
>>>> When s2 is the empty string, n is 0.
>>>
>>>>
>>>> What are the first 0 characters of s1? Clearly the empty string, since that is the only string with 0 characters.
>>>>
>>>> Do the first 0 characters of s1 match s2? Well they are both the empty string, and ""=="" is true, so…
>>>>
>>>> That would be a resounding “Yes!”
>>> how dumb (for “”.hasPrefix(“”) ), my mistake. (handled correctly imho in code example above)
>>> however, that is a matter of definition:
>>> should “search for nothing in nothing” return “true” ??
>>
>> Yes. For example, if you’re searching for “a” in the String “a”, you’d return true. Same thing for search for a nothing in a nothing-if the object is what you’re searching for, you can say it contains it.
>>
>>>
>>> Again, Strings to me are just character arrays…
>>>
>>>>
>>>> Nevin
>>>>
>>>>
>>>>
>>>> which, to me, implies that one will never find an occurrence
>>>> of an empty string within another string,
>>>> for the very simple reason that an empty string
>>>> does not exist within another string. **
>>>> Ergo: “false” is the right evaluation when s2.isEmpty.
>>>>
>>>> ** In my mental model, a String is just an array of 0...n characters,
>>>> like it is in most languages, very straightforward.
>>>>
>>>> (returning false) This is exactly the reason why NSString does that,
>>>> for more than 20 years, why change it?
>>>>
>>>> AFAIK no one has complained about this for years,
>>>> because imho it is logically sound.
>>>>
>>>> for a compiler this is very easy
>>>> all it has to do is to return False
>>>> when either s1 or s2 is empty.
>>>>
>>>>
>>>> Ted
>>>>
>>>>
>>>>> On 19.07.2016, at 23:11, Jacob Bandes-Storch <jtbandes at gmail.com <mailto:jtbandes at gmail.com>> wrote:
>>>>>
>>>>> Not that it's needed, but another +1 from me.
>>>>>
>>>>> a.hasPrefix(p) should be true iff there exists some string x for which p+x == a. If p == "", then x := a satisfies this, so hasPrefix should return true.
>>>>>
>>>>> Jacob
>>>>>
>>>>> On Tue, Jul 19, 2016 at 1:29 PM, Jaden Geller via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>>> Both `hasPrefix` and `hasSuffix` are analogous to the more general `hasSubset` function, which would return `true` for the empty set.
>>>>>
>>>>>> On Jul 19, 2016, at 12:32 PM, Bianca via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>>>>
>>>>>> > Empty set is a subset of all sets.
>>>>>>
>>>>>> True but all sets certainly do not _contain_ the empty set, which is what might be confusing, as the word "contains" in the context of sets implies that it's a member of the set of characters that make up a String.
>>>>>>
>>>>>> On Tue, Jul 19, 2016 at 12:23 PM Charlie Monroe via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>>>>
>>>>>> > On Jul 19, 2016, at 6:17 PM, Ted F.A. van Gaalen via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>>>>>> >
>>>>>> > 1. return “false” seems to me logically correct, because
>>>>>> > there is never an empty string in another string, and an empty string cannot contain another empty string, right?
>>>>>>
>>>>>> Empty set is a subset of all sets.
>>>>>>
>>>>>> Just like:
>>>>>>
>>>>>> let arr1: [String] = ["Hello", "Swift", "Evolution"]
>>>>>> let arr2: [String] = []
>>>>>> arr1.starts(with: arr2, isEquivalent: ==) // true
>>>>>>
>>>>>> > This has worked very conveniently for NSString in ObjC for more than 20 years, why change it?
>>>>>> > Do you know of cases that were problematic with this convention?
>>>>>> >
>>>>>> >
>>>>>> > 2 throw a runtime error when trying to do this:
>>>>>> > str.hasPrefix(“”) // also for hasSuffix, str.contains etc.
>>>>>> >
>>>>>> > some in-line questions below.
>>>>>> >
>>>>>> > Kind Regards
>>>>>> >
>>>>>> > Ted
>>>>>> >
>>>>>> >
>>>>>> > On 19.07.2016, at 16:31, Dave Abrahams <dabrahams at apple.com <mailto:dabrahams at apple.com>> wrote:
>>>>>> >>
>>>>>> >>
>>>>>> >> on Tue Jul 19 2016, "Ted F.A. van Gaalen" <tedvgiosdev-AT-gmail.com <http://tedvgiosdev-at-gmail.com/>> wrote:
>>>>>> >>
>>>>>> >>> Hi Dave
>>>>>> >>>
>>>>>> >>> “true” ? am I going nuts ? :o)
>>>>>> >>>
>>>>>> >>> var str = "Hello, playground"
>>>>>> >>>
>>>>>> >>> print( str.hasPrefix("”)) // case 1 : false
>>>>>> >>>
>>>>>> >>> print( str.hasSuffix("”)) // case 2 : false
>>>>>> >>>
>>>>>> >>> print("" == “a” ) // case 3 : false
>>>>>> >>>
>>>>>> >>> Currently, all cases above evaluate to “false”
>>>>>> >>> i think that is correct,
>>>>>> >>
>>>>>> >> I don't know what to tell you. It may seem intuitively correct to you,
>>>>>> >> but others in the thread have laid out the reasons why it is not
>>>>>> >> mathematically correct behavior.
>>>>>> > Where? I couldn’t find any.
>>>>>> >> One other way of rephrasing it: to get
>>>>>> >> `false` for str.hasPrefix(""), you actually need special-case code in
>>>>>> >> hasPrefix to check for the empty string,
>>>>>> > again, maybe it should throw a run-time error instead.
>>>>>> >
>>>>>> >
>>>>>> >> and the caller may well also
>>>>>> >> need special-case code to handle the fact that the result is not
>>>>>> >> mathematically consistent with other cases on the continuum.
>>>>>> > In this context as “continuum” :
>>>>>> > are you referring to “sets” or “collections” here?
>>>>>> > what other cases?
>>>>>> >
>>>>>> >> Doing
>>>>>> >> things that way doesn't work in practice for real programs.
>>>>>> > please explain thank you, because I see no problems at
>>>>>> > all with the current NSString-like evaluation…
>>>>>> > I’d put an s.isEmpty() in front of it.
>>>>>> >>
>>>>>> >>> because:
>>>>>> >>>
>>>>>> >>> How can an empty string be a prefix or suffix value?
>>>>>> >>> as there is no empty string present in a non-empty string.
>>>>>> >>>
>>>>>> >>> Note that if case 1 and case 2 would evaluate to “true”,
>>>>>> >>> it would conflict with case 3.
>>>>>> >>>
>>>>>> >>> Can’t imagine that case 3 should in future also result in “true”
>>>>>> >>>
>>>>>> >>> ??
>>>>>> >>>
>>>>>> >>> -----
>>>>>> >>>
>>>>>> >>> Also I hope that changes to String functionality
>>>>>> >>> for Swift 4 are not backward breaking changes
>>>>>> >>> even the more for string handling, because Strings
>>>>>> >>> are heavily used in most apps.
>>>>>> >>>
>>>>>> >>> I am firmly convinced that all future releases of Swift
>>>>>> >>> should compile Swift 3 and higher source files without
>>>>>> >>> any changes 100 % flawlessly! This prevents early diminishing
>>>>>> >>> of Swift’s popularity, especially with those building large
>>>>>> >>> codebases using Swift.
>>>>>> >>>
>>>>>> >>> I’ve started a thread about this a week ago,
>>>>>> >>> however no one found this important enough to
>>>>>> >>> share their opinions with me yet, or were too busy with
>>>>>> >>> other subjects to do so.
>>>>>> >>>
>>>>>> >>> Increasingly I have dreams, me
>>>>>> >>> programming complete apps in Smalltalk
>>>>>> >>> and then automagically generate
>>>>>> >>> an macOS, tvOS or iOS runtime app of it.
>>>>>> >>>
>>>>>> >>> (I have also dreams of this world becoming
>>>>>> >>> a nice and peaceful placebut that is
>>>>>> >>> beyond the context of this forum)
>>>>>> >>>
>>>>>> >>> Kind Regards
>>>>>> >>> TedvG
>>>>>> >>>
>>>>>> >>> www.speyer.de <http://www.speyer.de/>
>>>>>> >>>
>>>>>> >>>> on Mon Jul 18 2016, Kevin Nattinger <swift-evolution at swift.org <mailto:swift-evolution at swift.org> <mailto:swift-evolution at swift.org <mailto:swift-evolution at swift.org>>> wrote:
>>>>>> >>>>
>>>>>> >>>>> I agree, true is definitely the expected behavior. In particular, it
>>>>>> >>>>> seems absurd to me that `a.hasPrefix(b)` and `a.hasSuffix(b)` could be
>>>>>> >>>>> false when `a == b` is true.
>>>>>> >>>>
>>>>>> >>>> I expect to be reworking Strings for Swift 4, and this is one of the
>>>>>> >>>> many things we plan to address.
>>>>>> >>>>
>>>>>> >>>> --
>>>>>> >>>> Dave
>>>>>> >>>>
>>>>>> >>>>
>>>>>> >>>
>>>>>> >>
>>>>>> >> --
>>>>>> >> Dave
>>>>>> >
>>>>>> > _______________________________________________
>>>>>> > swift-evolution mailing list
>>>>>> > swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>> > https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>>
>>>>>> _______________________________________________
>>>>>> swift-evolution mailing list
>>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>> --
>>>>>> Bianca
>>>>>> http://biancatamayo.me <http://biancatamayo.me/>_______________________________________________
>>>>>> swift-evolution mailing list
>>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> swift-evolution mailing list
>>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>>>>
>>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> swift-evolution mailing list
>>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
>>> _______________________________________________
>>> swift-evolution mailing list
>>> swift-evolution at swift.org <mailto:swift-evolution at swift.org>
>>> https://lists.swift.org/mailman/listinfo/swift-evolution <https://lists.swift.org/mailman/listinfo/swift-evolution>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160720/bc504650/attachment.html>
More information about the swift-evolution
mailing list