8 ms·
>Zig is not a mature language. But it has made enough useful choices for a number of companies to invest in it and run it in production. The useful choices make
by coldtea 3y ago
>Zig is not a mature language. But it has made enough useful choices for a number of companies to invest in it and run it in production. The useful choices make Zig worth talking about.Go and Rust are mature languages. But they have both made questionable choices that seem worth talking about.
Well, Zig's native string type support, or lack thereof, is also a questionable choice. It's not like Zig did all the right choices and only Go and Rust made questionable ones.
- bsder 3y agoEverybody says they want a built-in String type. And then everybody proceeds to write their own String library anyway. "The only winning move is not to play."
- pornel 3y agoRust has a nice solution of having a &str slice (equivalent of C++ std::string_view) as the lowest common denominator and a deref operator that can easily coerce various string types to the slice. This allows Rust to have all kinds of string flavors (fixed-len or NUL-terminated or growable, on stack or heap or in ROM, with SSO, with CoW, interned or refcounted, atomically or not, and so on), but they all coerce to the basic &str, so they have the same basic methods, and are compatible with most functions that just want a string without caring how it's allocated. You can use your own weird string type if you want, but usually you're not forced to convert or copy it to use it with standard library functions or 3rd party dependencies.
- josephg 3y agoYeah - although the cost of this is that it makes rust harder to learn. (Try answering the common beginner question: “How is &String different from &str?”) In rust Strings are usually passed in to functions as a &str, and returned from functions as String. It makes sense once you’re used to it, but I think philosophically Rust is much closer to C++ than C. Rust is missing the elegant minimalism of C or Zig.
- iknowstuff 3y agoSimple is a lie: https://fasterthanli.me/articles/i-want-off-mr-golangs-wild-ride#simple-is-a-lie https://fasterthanli.me/articles/i-want-off-mr-golangs-wild-...
- pepa65 3y agoOP is not talking about Golang.
- iknowstuff 3y agoThe same critique applies
- pepa65 3y agoSo Zig is not simple but Rust is? The article you ref is not talking about Zig at all by the way.
- iknowstuff 3y agoIt just illustrates the point. There is no elegance in simplicity. Zig is not memory safe and its functions „assume” utf8 with UB when they encounter invalid bytes.
- duped 3y ago> Try answering the common beginner question: “How is &String different from &str?” This has nothing to do with strings though - how is &Vec<T> different from &[T] or &Box<[T]>? You need to understand ownership, references, and unsized types.
- josephg 3y ago> This has nothing to do with strings Sort of. It certainly affects strings, and you can't really use strings without understanding the difference. My point is that its yet another thing in the big bucket of junk you need to learn in order to use rust effectively. Rust is the only language I know of that has separate types for owned strings and a borrowed strings. Its a powerful concept - and its fast and efficient for the computer. But its not "free". The cost is that it makes it harder to learn rust. While we're on the topic - it also really doesn't help that the names of these types in the standard library are super idiosyncratic. String is to Vec<u8> as &str is to &[u8]. You just have to memorise that. How about Path and PathBuf? One of them is like String, and one is like &str. I swear I have to look it up every single time. I think the investment is worthwhile - I adore rust. But as I said, rust feels more like a better C++ than a better C. All the pain is front loaded, with the assumption that you'll eventually write enough software in rust to make the investment worthwhile. Simpler languages like Python or Go get out of your way immediately and let you be productive. I prefer rust, but there's definitely something to be said for that attitude.
- neonsunset 3y agoYup, I can’t imagine switching to a language that doesn’t have something like that, since in C# you have a similar feature in the form of Span<T> and ReadOnlySpan<T>, to which all manners of sources can be coerced: heap-allocated arrays, stack-allocated buffers, inline arrays, strings, native memory, etc.
- DinaCoder98 3y ago> And then everybody proceeds to write their own String library anyway. Is this true? It was (is!) certainly true for C, but C has an especially emaciated expectation for string processing primitives. Any runtime developed after like 1995 that I can think of has fixed this by providing a sane string implementation people generally agree upon.
- slimsag 3y agoIf you care about Unicode for real, yes. Rust and Go both don't have a builtin package for grapheme iteration - and many naively (and incorrectly) think that a 'Go unicode rune == "character"' in Go. I assume the same happens with Rust `char` type. If you care about unicode-aware string sorting (you should), rather than the naive string sorting the Go and Rust standard libraries provide out of the box... then you probably want a proper Unicode library. I think the only language that gets Unicode 'right' out of the box is Swift, as it actually provides grapheme iterators, Locale awareness, etc. - but it comes at the cost of the language being tied to the (ever-moving) Unicode standard.
- deleted 3y ago[deleted]
- DinaCoder98 3y agoI was pessimistic about grapheme-based orientation towards text, deleted it to research more, and I've come to the conclusion that this is simply not a consensus opinion. Can you give me an example where grapheme-based sorting makes a critical difference from codepoint-oriented sorting on a normalized text? Full unicode composition certainly seems to provide a reasonable solution with western languages, CJK characters, and romanization of CJK characters, but that leaves a hell of a lot of scripts that I don't know about. I mean unicode is incredibly complex, but it doesn't even seem like there's a consensus outside of swift's string implementation of what a grapheme even is. (Granted, this might support the above concept that people can't even agree on what a string is, but unicode code points seems like a reasonable baseline to expect from a modern language. That said, rust doesn't even include unicode normalization in the standard library, although the common crate for it seems like a reasonable solution.)
- MBCook 3y agoI’ve used Java my entire career. I have seen a custom string type nor a post advocating it in Java.
- dleslie 3y agoNever seen one for C#, either.
- neonsunset 3y agoApologies for the plug haha https://github.com/U8String/U8String https://github.com/U8String/U8String With that said, implementing it is not easy, especially in terms of ensuring it is as fast as built-in string or faster (because the project goal is to be faster than built-in string and Go implementation, and match or outperform Rust's String where applicable). I can't imagine something like that being possible in e.g. Java or most other high-level languages - they simply do not expose appropriate low-level primitives when you need a "proper" string type.
- MBCook 3y agoWell, I see I left the word “not” out which makes this a little more confusing. Oops. It’s supposed to be “I have NOT seen”.
- pyrolistical 3y agoWhat advantages would there be with a native string type over []const u8. (For those not fluent in zig, a string is typed as a slice constant bytes, where a slice is a pointer + length)
- Ygg2 3y agoAn UTF8 String would have invariant of always having valid UTF8, omitting need for further UTF8 validation. If you're working on bytes string in Zig the status of them is unknown, so you have to always validate even if it's just Utf8. In Rust you can omit Utf8 validation for bytes from a String.
- slimsag 3y agoIn Zig strings are assumed to be UTF8 unless documented otherwise, so any function operating on strings is not wasting CPU cycles doing any validation. The person who creates the string is expected to ensure it is valid UTF8 if needed.
- tialaramex 3y agoThis is the "Just don't write bugs" that we laugh at for C and C++.
- Ygg2 3y agoIf there is one thing Ada does better than Rust, is that it encodes the invariants in the type system. While Rust doesn't goes as far as I would have want it's miles better than what Zig and C are doing - the programming equivalent of "Trust me bro!".
- binary132 3y agoConstructing a runtime-invariant-checked utf8 string is not "omitting utf8 validation".
- wavemode 3y agoWell, Zig does have Unicode support in its standard library. A "String" type wrapping that functionality would be slightly safer but, I don't see it as some huge wart of the language. You could always just define your own.
- floobertoober 3y agoThe more I've used the language, I'm starting to think that this decision makes sense in the context of Zig. Common string operations involve allocation, non-constant time access, etc. I can definitely understand how strange that sounds without the rest of the language around it as context, though.
- deagle50 3y agothe inclusion of `bufPrint` in the standard library is really nice, you can just give it a pointer to an array. If you want to make a string on the stack in Rust you have to pull in something with a `Writer` trait like `ArrayVec` and use `write!`.
- tialaramex 3y agoRust's String requires allocation, but str (typically seen as the fat pointer type &str) does not. "The cat sat on the mat".split('a') is an iterator over sub-strings, no more allocation needed here than for 105u32.leading_zeros() A lot of the Rust string API lives in str, not String.
- emidoots 3y agoIn fact, Zig has pretty much the same support for strings as both Rust and Go. The primary difference which people seem to complain about, that "[]const u8" is not written as "string", can be solved by writing `const string = []const u8;` at the top of your program if you like. Rust: `&str`, 'some bytes, and a length', 'Constructing a non-UTF-8 string slice is not immediate undefined behavior, but any function called on a string slice may assume that it is valid UTF-8, which means that a non-UTF-8 string slice can lead to undefined behavior down the road.' - also `String` and `OsString`. edit: apparently Rust enforces that &str cannot be created with invalid UTF8, at the additional performance cost of runtime checks, so it has stronger guarantees than other languages like Go/Java/Zig/etc (as usual) Go: `string`, 'in effect a read-only slice of bytes', 'a string holds arbitrary bytes. It is not required to hold Unicode text, UTF-8 text, or any other predefined format. As far as the content of a string is concerned, it is exactly equivalent to a slice of bytes.' Zig: `[]const u8`, 'some bytes, and a length', 'Zig has no concept of strings', 'by convention parameters that are "strings" are expected to be UTF-8 encoded slices of u8.', 'Generally, you can use UTF-8 and not worry about whether something is a string.' - and the stdlib has functions for working with unicode and strings.
- Ygg2 3y ago> Rust: `&str`, 'some bytes, and a length', 'Constructing a non-UTF-8 string slice is not immediate undefined behavior If you're constructing invalid `str` you already have severely fucked up. And dog is eating your HDD.
- DinaCoder98 3y ago> If you're constructing invalid `str` you already have severely fucked up. Presumably it'd be better to know this immediately on initialization of the variable rather than at some point in the program that actually expects valid utf8—god forbid you transmit or persist the data before this happens.
- duped 3y agoThat's why str::from_utf8 returns Result<&str, FromUtf8Error>. And if you know the string is UTF-8 encoded and don't want to pay the cost, there's `from_utf8_unchecked`, which is marked unsafe.