4 ms·
I think you have this backwards. Go is explicitly optimized for software engineering; in fact, it's the only language I'm aware of that makes large-scale engine
by nemo1618 5y ago
I think you have this backwards. Go is explicitly optimized for software engineering; in fact, it's the only language I'm aware of that makes large-scale engineering its north star. Here's Rob Pike discussing how Go's design decisions make building and maintaining large programs easier: https://talks.golang.org/2012/splash.article https://talks.golang.org/2012/splash.article
(AFAICT, Rust was not named after "collecting Rust," and long-term maintenance is not one of its primary design goals.)
As an example, one celebrated feature of Go is that "all Go programs looks familiar," i.e. it's easier to get oriented in an unfamiliar Go codebase than just about any other mainstream language. Partly this is due to `gofmt`, but also the fact that the language itself is relatively spartan, with few dark corners. It's an "unsophisticated" language, which obviously cuts both ways.
Rust, by comparison, is a highly complex language. It allows for very powerful abstractions -- as well as very bespoke and "clever" constructs. I think Rust will develop a solid reputation for correctness, much like Haskell; Rust programs will run for many years without bugs or performance issues. But, again like Haskell, Rust will also have a reputation for allowing clever programmers to write too-clever code. That's why Go will prove to be the more maintainable language: because it intentionally limits expressiveness (a highly unpopular decision, unsurprisingly) and thereby limits the amount of "damage" any given programmer can do.
- alricb 5y agoEiffel might be another.
- nemo1618 5y agoI don't know much about Eiffel; do you know of any articles or talks that discuss its design tradeoffs?
- Jtsummers 5y agoEiffel's bigger contributions are probably: Design-by-contract. The contracts aren't just comments, they aren't haphazardly enforced by adding asserts to the code. They're explicit parts of the language which allows for a lot of interesting consequences when utilized. Testing can be semi-automated directly from the code, some elements of the program design can be proved to be satisfied statically without the need for compilation and execution. The ability to encode your specification into the language is incredibly useful. Command-query separation. If methods return a value (queries) they should be referentially transparent, having no side effects. This is a principle so not an explicit language feature, but it can be enforced using DbC.
- Jtsummers 5y ago> [Go]'s the only language I'm aware of that makes large-scale engineering its north star. Ada, Eiffel, Java, Pascal and derivatives, C#, Rust. Probably many others but I'd argue outside of tooling (which Go is particularly good at and has done an incredible job of standardizing, Rust being a peer in that regard with cargo) these languages are as good or better than Go for software engineering.
- nemo1618 5y agoBy "north star" I mean the guiding principle that other aspects are sacrificed for. A heuristic might be: "[Lang] would not be [lang] without [aspect]." I'm sure that the Rust team wants Rust to be a good language for large-scale engineering, but it's not their north star; "fearless concurrency" is probably the closest. For example, Rust is willing to sacrifice simple syntax and fast compile times to achieve more safety; Go is not. I don't know enough about the other languages to speak confidently about them, but if you can point me to any source materials (i.e. articles or talks by the language creators) that discuss large-scale engineering, I'd be interested to read them!
- kbenson 5y ago> it's not their north star; "fearless concurrency" is probably the closest. That's just a more recent slogan to succinctly express what their real north star means. Their real north star is "safety and correctness", and like all languages, they push to make the most important thing to them easy and approachable. Here's the thing, I'm not sure as a project saying your focus is large scale engineering and pushing towards that actually gets you closer to the desired result in the end than pushing for safety and correctness instead. I could fully see a language that pushes for safety and correctness eventually being a much better and easier to use choice when evaluating with respect to large scale engineering, because those are extremely important to large scale engineering.
- nemo1618 5y agoSafety and correctness certainly are important -- but they're also orthogonal to maintainability (among other values)! It's good to have most of the core values in common, but a language's guiding principle manifests in many small ways that can be very compelling in aggregate. Go's weird capital-letter namespace visibility rule is a great example of this: it has nothing to do with safety or correctness, but it's enormously helpful for getting your bearings in unfamiliar code, because it localizes an important piece of information, saving you a context-switch. Sure, another language might hit upon this feature incidentally (Rust has conventions around capitalization, and IIRC Haskell enforces it to some degree), but how many languages will chance upon all of the little things that make for a great engineering language?
- gher-shyu3i 5y ago> Go is explicitly optimized for software engineering; There's nothing to back up this claim. Using golang in practice shows otherwise. The mess resulting in large code bases is much more difficult to deal with compared to Java for instance.
- woah 5y agoGo inevitably results in a very large codebase for a given piece of functionality, especially if it’s used alongside Google’s companion projects such as protobufs and grpc. Lack of generics means that it is impossible to generalize over related types, leading to duplicated code, and in some cases, crazy hacks like serializing a struct, passing it through the generic part of the code and then deserializing it again when you need to use it. Other choices such as structs being initialized with “zero values” in their fields (instead of having a compile error when you forget a field), and the complicated sometimes equivalence of zero values and null create a lot of footguns when refactoring. Go’s strength is a batteries included stdlib and its looseness can make prototyping faster. But it feels very much like an old school scripting language like php or js, where you have to use countless trivial unit tests to have any confidence about what your code is doing.
- meritt 5y ago> where you have to use countless trivial unit tests to have any confidence about what your code is doing. I don’t understand this. I can read well written code and tell you what it does, including in old school scripting languages. I don’t need countless trivial unit tests.
- brson 5y agoRust was explicitly designed from the beginning for creating maintainable large-scale software. Here's the original elevator pitch from 2010: https://github.com/rust-lang/rust/blob/d6b7c96c3eb29b9244ece0c046d3f372ff432d04/doc/rust.texi#L104 https://github.com/rust-lang/rust/blob/d6b7c96c3eb29b9244ece... Note the text about "programming in the large".