4 ms·
Depends what you mean by type safety. If by type safety you mean free from segfaults, Go is very much type-unsafe (send a map over a channel, access it concurre
by ootachi 15y ago
Depends what you mean by type safety. If by type safety you mean free from segfaults, Go is very much type-unsafe (send a map over a channel, access it concurrently, and it will segfault).
- drivebyacct2 15y agoMaybe I'm mistaking terminology but that doesn't seem like a type issue you're describing.
- ootachi 15y agoThere's no one definition of type safety. It ultimately depends on what your type system is trying to enforce. I strongly suspect, however, that most programmers expect "type-safe" languages to enforce memory safety, and that Go's lack of memory safety is surprising in this context.
- enneff 15y agoThat is a very unusual definition of "type safety." What you're describing is more commonly known as "thread safety," in my experience. By your definition, is Java type safe? You still need to guard against concurrent mutation of shared data in Java and in most other languages that support shared mutable state. We typically describe Go as "memory safe," in that you can't address uninitialized memory (unless you import package "unsafe", which clearly demonstrates your intent).
- ootachi 15y agoJava is type safe, because the language defines clear semantics for what happens when you mutate two memory locations simultaneously (you get one result or the other). Under no circumstances does the program have truly undefined behavior. Java HashMaps aren't thread-safe, but they will just do the wrong thing when you try to access them concurrently. Under no circumstances will the program be able to read or write undefined memory. By contrast, your Go program's behavior becomes undefined when you mutate and read a hashmap concurrently among multiple threads. Anything can happen. Edit (addressing the reply below): That's fascinating, thanks. It really speaks to the wisdom of writing hash maps in the library, on top of the language, rather than unsafely in the runtime as Go does. (This would unfortunately require generics, so it's not an option for Go.) It's very difficult to predict all that can go wrong with unsynchronized access to data structures that aren't designed to be thread safe. The beauty of Java here is that the core primitives can never lead to accessing undefined memory, and therefore hash tables, however badly they mess up, will never lead to that core principle being violated. This is critical for security, for example.
- smanek 15y agoIncidentally, I've seen unsynchronized access to a Java HashMap cause an infinite loop on .get()s which is (allowably) undefined behavior, and pretty unexpected (see: http://mailinator.blogspot.com/2009/06/beautiful-race-condition.html http://mailinator.blogspot.com/2009/06/beautiful-race-condit...)
- spand 15y agoThere is quite the difference between libraries having undefined behavior if you do not follow their contract and the language.
- jongraehl 15y agoI agree with everything you've said in this thread, except this: "type safety" should mean that the system has some belief about the type of values that cannot be compromised. (sometimes type safety can be proven absolutely by static checking, but you have otherwise only run-time type checking, e.g. dynamic JVM languages, introspection). Unlimited memory corruption does seem to imply that run-time type guarantees are gone, but it's still better to use the most appropriate terms.
- enneff 15y ago> send a map over a channel, access it concurrently, and it will segfault Not exactly. Go's maps may safely be read from multiple threads simultaneously, but writing at the same time as reading or writing will yield undefined behavior. Go programs don't segfault like C programs. They typically panic, providing a descriptive stack trace of where the problem arose. As I mentioned in my other thread, what you're describing are "thread safe data structures," which Go doesn't provide by default. We provide the fast and non-thread-safe data structures and let the programmer build the concurrency mechanisms around them (easily done with a lock or using goroutines/channels).
- ootachi 15y ago"Undefined behavior" is the problem here. In Java, you can create data races, but you can't cause memory errors.
- canop_fr 15y agoWhat do you mean ? I you don't use synchronization protection when you access your structures from different threads, you'll have the same inconsistency in your data. Using the explicit Mutex of Go doesn't seem so different than creating an object on which synchronizing your blocks as you do in Java. Or do I miss something in your comment ? EDIT : In my opinion, a program that doesn't crash and goes on running with inconsistent data structures is mainly hiding a failure which will appear in a worse way later (for example when those data will be used). To fail fast is often more secure. But my opinion may be based on the fact that I see too many java programs which seem to work but that nobody can touch because they're just in the lucky state where bugs don't surface too much.
- ootachi 15y agoMutating a hash map in Java while another thread reads it won't cause bad things like: (a) memory you don't have access to to be read; (b) other threads to crash; (c) the VM state to be corrupted; (d) the GC to crash; and so on. The Java world is still in a consistent state. In a security-oriented world, this is important. To the reply: It's a bit pedantic for me to say this, I know, but that's still "a consistent state". Basically, a Java program can't do anything it wouldn't otherwise be able to do by modifying a hashmap concurrently. Java programs can go into infinite loops. They can't access uninitialized memory.