7 ms·
The 'String', '~str' dichotomy is really unfortunate.
by Mr_T_ 11y ago
The 'String', '~str' dichotomy is really unfortunate.
- Jweb_Guru 11y agoThere is no ~str, but when there was it was largely identical to what String is now.
- pcwalton 11y agoPresumably you mean String/&str? (~str hasn't existed for a long time.) On the contrary, the lack of the string/string-view distinction is widely considered a flaw in the C++ standard libraries. C++14 introduces std::string_view to correct it. Rust's String/str distinction is just the same as C++14's std::string/std::string_view.
- frowaway001 11y agoApart from the Rust's usual rule to invent some abbreviations, but only apply them half the time. Then "types start with an uppercase letter" except when the language creators break their own rule. Then the fun "sometimes we use () and sometimes we use [] to do practically the same thing". Then the various insanities with ::. Then Generics. How many examples of languages which tried to use <> for Generics do we actually need before people learn the lesson? I really wished some people took Rust, and wrote a new frontend to get rid of all the pointless inconsistencies and other "C did, so it has to be good"-isms (like_all_this_underscore_stuff or the ridiculous abbreviations), because many ideas of Rust are not only good but brilliant and deserve to be put into languages which don't belong to the purely-academic category. I really wish Rust to succeed, but can we stop this approach of "3 steps forward and 2 steps backward" to language design?
- pcwalton 11y ago> Apart from the Rust's usual rule to invent some abbreviations, but only apply them half the time. Do you have an example? > Then "types start with an uppercase letter" except when the language creators break their own rule. They always start with a capital letter, except for built-in types or FFI bindings to libraries such as libc where the original types used a lowercase letter. This convention is exactly the same as Java. > Then the fun "sometimes we use () and sometimes we use [] to do practically the same thing". I've never heard this before. Do you have an example? () is used for function calls, grouping, and tuples, while [] is used for array literals and array indexing. > Then the various insanities with ::. The double-colon is very useful so that you can tell the difference between module lookup and field projection/method calling. Early Rust used . for module lookup, and it was confusing to tell at a glance whether a function was being called or a method was being invoked. > Then Generics. How many examples of languages which tried to use <> for Generics do we actually need before people learn the lesson? Using square brackets like Scala wouldn't actually help with the ambiguity, because it would be ambiguous with array indexing. The only syntax I've seen that actually solves the ambiguity is D's `!()`, which was deemed too unfamiliar. Angle brackets were chosen because they are familiar and aren't really any worse than the other mainstream options. > I really wished some people took Rust, and wrote a new frontend to get rid of all the pointless inconsistencies and other "C did, so it has to be good"-isms (like_all_this_underscore_stuff or the ridiculous abbreviations) The underscore naming convention was actually taken from Python's PEP 8. Rust doesn't really have any more abbreviations than most other languages at this point.
- callahad 11y ago> > Then the fun "sometimes we use () and sometimes we use [] to do practically the same thing". > I've never heard this before. Do you have an example? () is used for function calls, grouping, and tuples, while [] is used for array literals and array indexing. Maybe referring to the ability to use either type of brace with macros?
- pcwalton 11y agoYeah, you can use any type of delimiter with macros, but I think that's an important feature, especially since macros can expand to declarations. Early versions of Rust required parentheses for all macro invocations, and that looked really ugly for anything that looked like a block. Delimiter interchangeability is a feature from Racket that works really well when it comes to macros and I'd hate to give it up.
- blaenk 11y agoAgreed. They allow you to naturally create vectors with the bracket delimiter `vec![1, 2, 3]`, create spawn-like macros with the brace delimiter `spawn { code }`, and in the normal case just use parentheses `println!("testing")`
- frowaway001 11y agoConsidering the glorious downvoting, I won't bother comment any further except saying that these "issues" Rust devs keep pointing out have been addressed. And now, I won't waste any further time with this cult.
- Daishiman 11y agoIt's so sad, because I yet to see a single place where they're addressed.
- frowaway001 11y agoYes, but getting 8 downvotes in two comments ... why should I care?
- mbrubeck 11y agoIn this example the dichotomy is between String (which is guaranteed by the type system to be valid UTF-8) and OsStr (which might be in an unknown encoding or otherwise not decodable to valid Unicode). This is exactly when you want a systems language to require explicit conversions, rather than converting things silently and possibly losing or corrupting data.
- davvid 11y agorather than converting things silently and possibly losing or corrupting data Exactly. Python3 went down the "silently converting" route, and it's not pretty[1]. I would go so far as to call it harmful. http://lucumr.pocoo.org/2014/5/12/everything-about-unicode/ http://lucumr.pocoo.org/2014/5/12/everything-about-unicode/ I understand the difficulty in this space; much of it is caused by forcing the Windows unicode filesystem API onto python as its world-view, rather than sticking to the traditional Unix bytes world-view. I'm unixy, so I'm completely biased, but I think adopting the Windows approach is fundamentally broken.
- Veedrac 11y agoThe problem there is overblown - it's basically all due to the idea that sys.stdin or sys.stdout might get replaced with streams that don't have a binary buffer. The simple solution is just not to do that (and it's pretty easy; instead of replacing with a StringIO, replace it with a wrapped binary buffer). Then the code is quite simple import sys import shutil for filename in sys.argv[1:]: if filename != '-': try: f = open(filename, 'rb') except IOError as err: msg = 'cat.py: {}: {}\n'.format(filename, err) sys.stderr.buffer.write(msg.encode('utf8', 'surrogateescape')) continue else: f = sys.stdin.buffer with f: shutil.copyfileobj(f, sys.stdout.buffer) Python's surrogateescape'd strings aren't the best solution, but I personally believe that treating unicode output streams as binary ones is even worse.