[swift-evolution] Change Request: Make myString.hasPrefix("") and myString.hasSuffix("") return true

Ted F.A. van Gaalen tedvgiosdev at gmail.com
Wed Jul 20 20:02:58 CDT 2016


Hi Nevin,

extension String
{
    var count: Int
        {
        get
        {
            return self.characters.count
        }
    }
    
    // Sigh... String subscriptors should be already builtin in the String
    
    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> 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” ??

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>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160721/e8cd7ea4/attachment.html>


More information about the swift-evolution mailing list