4 ms·
> The only modern language that gets it right is Swift: I disagree. What is the "right" things is use-case dependent. For UI it's glyph bases, kinda, more pr
by dathinab 3y ago
> The only modern language that gets it right is Swift:
I disagree.
What is the "right" things is use-case dependent.
For UI it's glyph bases, kinda, more precise some good enough abstraction over render width. For which glyphs are not always good enough but also the best you can get without adding a ton of complexity.
But for pretty much every other use-case you want storage byte size.
I mean in the UI you care about the length of a string because there is limited width to render a strings.
But everywhere else you care about it because of (memory) resource limitations and costs in various ways. Weather that is for bandwidth cost, storage cost, number of network packages, efficient index-ability, etc. etc. In rare cases being able to type it, but then it's often us-ascii only, too.
- hot_gril 3y agoSwift made an effort to handle grapheme clusters but severely over-complicated strings by exposing performance details to users. Look at the complex SO answers to what should be simple questions, like finding a substring: https://news.ycombinator.com/item?id=32325511 https://news.ycombinator.com/item?id=32325511 , many of which changed several times between Swift versions I was working on an app in Swift that needed full emoji support once. Team ended up writing our own string lib that stores things as an array of single-character Swift strings.
- marcellus23 3y ago> many of which changed several times between Swift versions This was true while Swift was developing but it's been stable now for several years. At some point that complaint is no longer valid.
- hot_gril 3y agoYou still see all the answers from old versions sitting around, often at the top. Part of it is because of how often they changed such fundamental things. String length changed 3 times. Every other language figured these things out before the initial non-beta release.
- marcellus23 3y agoThe last time the string API changed was in 2017. That was 6 years ago.
- hot_gril 3y agoAlso, realized "needed full emoji support" sounds silly. It needed to do a lot of string manipulation, with extended grapheme clusters in mind, mainly for the purpose of emojis.
- ssokolow 3y ago*nod* Rust was given as one of the examples and Rust's .len() behaviour is chosen based on three very reasonable concerns: 1. They want the String type to be available to embedded use-cases, where it's not reasonable to require the embedding of the quite large unicode tables needed to identify grapheme boundaries. (String is defined in the `alloc` module, which you can use in addition to `core` if your target has a heap allocator. It's just re-exported via `std`.) 2. They have a policy of not baking stuff that is defined by politics/fiat (eg. unicode codepoint assignments) into stuff that requires a compiler update to change. (Which is also why the standard library has no timezone handling.) 3. People need a convenient way to know how much memory/disk space to allocate to store a string verbatim. (Rust's `String` is just a newtype wrapper around `Vec<u8>` with restricted construction and added helper functions.) That's why .len() counts bytes in Rust. Just like with timezone definitions, Rust has a de facto standard place to find a grapheme-wise iterator... the unicode-segmentation crate.
- layer8 3y agoArguably, you don’t need any (default) length at all, just different views or iterators. When designing a string type today, I wouldn’t add any single distinguished length method.
- galad87 3y agoSwift string type has got many different views, like UTF-8, UTF-16, Unicode Scalar, etc… so if you want to count the bytes or cut over a specific byte you still can.
- dathinab 3y agothat's not the issue defaults matter as in they should things you can just use by-default without thinking about it as swift is deeply rooted in UI design having a default of glyphs make sense and as rust is deeply rooted in unix server and system programming utf-8 bytes make a lot of sense through the moment your language becomes more general purpose you could argue having a default in any way is wrong and it should have multiple more explicit methods.
- toast0 3y ago> as in they should things you can just use by-default without thinking about it That time has passed. If you want to know the length of a string, you really should indicate what length type you mean.
- hot_gril 3y agoThere was no string.length in Swift for a while. Then they added one that just does what the user expects, get the number of grapheme clusters. If a user figures out that this isn't what they want, they can go use the other length method.
- dathinab 3y agoexcept if it's server swift code, then it doesn't do what the user expects at all
- hot_gril 3y agoThe most common reason I can think of a server wanting the string length is because it's enforcing a character limit in some field, in which case it does what the user expects. You aren't often manually managing memory in Swift. On top of that, Swift on server is probably rare to begin with.
- patrickas 3y agoThat is why I like the way Raku handles it. It has distinct .chars .codes and .bytes that you can specify depending on the use case. And if you try to use .length is complains asking you to use one of the other options to clarify your intent. my \emoji = "\c[FACE PALM]\c[EMOJI MODIFIER FITZPATRICK TYPE-3]\c[ZERO WIDTH JOINER]\c[MALE SIGN]\c[VARIATION SELECTOR-16]"; say emoji; #Will print the character say emoji.chars; # 1 because on character say emoji.codes; # 5 because five code points say emoji.encode('UTF8').bytes; # 17 because encoded utf8 say emoji.encode('UTF16').bytes; # 14 because encoded utf16