Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Putting Rust and Go together under strong type system is a very odd choice.

Rust is inspired by ML family languages and heavily leans on it's type system, while Go is very simplistic in comparison. (This has improved somewhat with the recent addition of generics)



Yup. For example, in both Rust and Go you can cheerfully open a filename, based on a string you found in some JSON. But the reason why you can do that is very different, and reveals important foundational differences.

In Go the answer is that strings are just some bytes, and filenames are just some bytes and so this naturally just works.

In Rust the answer is that strings are AsRef<Path> and you can open a Path, so when you call open the compiler gives it a Path even though that isn't what you actually had (you can't mutate the Path via this reference, so we know open doesn't change it).

The difference becomes more stark if we go the other way, starting from a list of files in the current directory and writing a JSON file.

In Go if you get a list of all the filenames in the current directory, it's a list of strings, and the fact that those aren't actually text is your problem, you will need to explicitly take care of this or you can't emit valid JSON.

In Rust, you get Paths, and you're going to need to explicitly ask for the strings to make JSON, at which point you have to decide what you want to do if the Path isn't just text, you're obliged to decide, even if it's just panic (ie abort the program).


> In Go if you get a list of all the filenames in the current directory, it's a list of strings, and the fact that those aren't actually text is your problem, you will need to explicitly take care of this or you can't emit valid JSON.

You'll still emit valid json. The encoding/json doc says:

> String values encode as JSON strings coerced to valid UTF-8, replacing invalid bytes with the Unicode replacement rune.


The original filenames will be lost though, if they weren't utf-8.


But to be fair if we're sending them as UTF-8 in a JSON file we can't do anything about that.

I've had situations where I am obliged to write output to XML, and clients are like, "You can't lose this weird data in our text". That's not me, that's XML, in XML 1.0 most of the ASCII Control Characters are banned (not like "You must escape this character" they are banned if you write them as text, escaped or not, that's not a valid XML file and some parsers won't read it). You can either admit you want binary data maybe wrapped as Base64 inside the XML or you can accept that in XML those characters are toast. I would turn all the banned characters into U+FFFD in XML.

JSON doesn't have that defect, but it still can't magically make non-text into text, and some filenames are not text. So this feels fair enough. Chances are if your JSON format is so capable that you can write "Here's a Non-text filename" and have that work almost all the people parsing it ignore that case and you didn't really improve interoperability at all.


Aha, useful. Good catch.


I agree - Go's type system would be perhaps better described as strict. There are rarely cases in which conversion is implicit (not particularly unique to Go, but useful). Between types are aliases of those types? No. Between signed and unsigned? Of course not. Between string and []uint8? No. What about less precise to more precise? Nope. This can be a pain, but overall it avoids some classes of bugs present in languages like C (without getting strict about your compiler flags anyway) and allows you to use types to encode your problem in a way that prevents dumb mistakes.


Especially with how Go handles default values. Suddenly a value wasn't present in a deserialization and now that's a nil pointer. Or if you have a stateful 0 so you can't tell the difference between missing or user choice without a deeply awful extra check.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: