8 ms·
Typical gatekeeping. I like Go, because it lets me get stuff done. You could say the same about JavaScript, but I think Go is better because of the type system.
by svnpenn 5y ago
Typical gatekeeping. I like Go, because it lets me get stuff done. You could say the same about JavaScript, but I think Go is better because of the type system. C, C++ and Rust are faster in many cases, but man are they awful to work with.
C and C++ dont really have package management to speak of, its basically "figure it out yourself". I tried Rust a couple of times, but the Result/Option paradigm basically forces you into this deeply nested code style that I hate.
- dahfizz 5y ago> C and C++ dont really have package management to speak of I hear this complaint often, but I consider it a feature of C. You end up with much less third party dependencies, and the libraries you do end up using have been battle tested for decades. I much prefer that to having to install hundreds of packages just to check if a number is even, like in JS.
- dcgudeman 5y agoHmm yes, why stop there? Why have functions? Just reimplement business logic all over your codebase. That way each block of code has everything you need to know. Sure, functions have been adopted by every other language/ecosystem and are universally known to be useful despite a few downsides but you could say the same about package management and that hasn't deterred you yet.
- dahfizz 5y agoYou're arguing against a straw man. I could just as easily say "why not make every line of code it's own function?" C has libraries, and my comment made it clear that they are useful. Argue against my actual point: By not having a bespoke package manager, and instead relying on the system package manager, you end up with higher quality dependencies and with dramatically less bloat in C than other language ecosystems. It is all the benefit and none of the drawbacks of npm-like ecosystems.
- dcgudeman 5y agoI don't agree with your assessment that libraries in C are higher quality. Additionally I have yet to see a system package manager that enables developers to install dependencies at a specific version solely for a project without a lot of headaches. All the venv stuff in python is necessary python dependencies are installed system wide. The idea that the C/C++ ecosystem is better off because it doesn't have its own package manager is a bizarre idea at best.
- imtringued 5y agoI'm one of the few humans on the planet that installs his dependencies inside the project folder and uses PYTHONPATH.
- pjmlp 5y agoAh, that is why all major OSes end up having some form of POSIX support to keep those C applications going.
- dahfizz 5y agoYou need have some OS API, what is wrong with POSIX? And what does POSIX have to do with package management?
- remexre 5y agomy big personal nit is poor async support; e.g. async disk IO is recent in Linux, and AFAIK all the Unices implement POSIX aio as a threadpool anyway. not being able to wait on "either this mutex/semaphore has been signaled, or this IO operation has completed" is also occasionally very annoying...
- pjmlp 5y agoPOSIX is UNIX rebranded as C runtime for OSes that aren't UNIX.
- dahfizz 5y agoI don't even know how to parse that. POSIX is a standard which was based on the unix OS's of the time. POSIX is an API, not a runtime. Only Unix systems today implement posix (MacOs, Linux).
- pjmlp 5y agoYes it is a standard, just like ISO C one is, and traditionally they go go together, just like you never use IP on its own. I suggest you to have a look around RTOS, mainframes, BeOS, and even NT history regarding POSIX support.
- throwaway894345 5y agoI think you're contradicting yourself. You end up with fewer third party dependencies in C because C developers end up rewriting from scratch what they would otherwise import, and these rewrites have much less battle-testing than popular libraries in other languages. Moreover, they also have more opportunity for failure since C is so much less safe than other languages. Even in those few libraries which have received "decades of battle-testing" we still see critical vulnerabilities emerge. Lastly, you're implying a dichotomy between C and JS in a thread about Go, which doesn't have the same dependency sprawl as JS.
- steveklabnik 5y ago> You end up with much less third party dependencies, https://wiki.alopex.li/LetsBeRealAboutDependencies https://wiki.alopex.li/LetsBeRealAboutDependencies
- dahfizz 5y agoThis just proves my point. A complex, fully featured GUI application written in C needs 122 libs total. In Rust, just installing SQLx for sqlite bindings requires 75 crates. And sqlite is one very small part of what rviz does. An rviz equivalent written in rust would require an order of magnitude more dependencies.
- averagedev 5y agoI've found Go to be much simpler than Rust, especially syntax wise. However, in Rust you can use the ? operator which propagates errors. In Go you have to check err != nil.
- svnpenn 5y ago> Rust you can use the ? operator That doesnt work with all types: https://stackoverflow.com/a/65085003 https://stackoverflow.com/a/65085003
- jdmnd 5y agoIt works for any type that implements the `std::error::Error` trait; which is something you can easily implement for your own types. If you want your errors to be integers for some reason, you can wrap that type in a zero-sized "newtype" wrapper, and implement `Error` for that. The Stack Overflow answer you linked seems to be claiming that it's simply easier to return strings, but I wouldn't say this is a restriction imposed by the language.
- svnpenn 5y ago> easily implement for your own types have you ever actually done that? I have, its not easy. Please dont try to hand wave away negatives of the Rust type system.
- mcronce 5y agoI do it frequently. It is indeed easy
- TheDong 5y ago> have you ever actually done that? I have, its not easy. Yes. I do it frequently. "#[derive(Error, Debug)]": https://github.com/dtolnay/thiserror#example https://github.com/dtolnay/thiserror#example Much easier than implementing the error interface in go. Rust is powerful enough to allow macros to remove annoying boiler-plate, and so most people using rust will grab one of the error-handling crates that are de-facto standard and remove the minor pain you're talking about. In go, it's not really possible to do this because the language doesn't provide such macros (i.e. the old third-party github.com/pkg/errors wanted you to implement 'Cause', but couldn't provide sugar like 'this-error' does for it because go is simply less powerful). I've found implementing errors in go to be much more error-prone and painful than in rust, and that's not to mention every function returning untyped errors, meaning I have no clue what callers should check for and handle new errors I add.
- pornel 5y agoNobody's saying you can't use Go or must use C/C++/Rust. If Go works for you, that's great. The issue is about positioning of Go as a language. It's confusing due to being (formerly) marketed as a "systems programming language" that is typically a domain of C/C++/Rust, but technically Go fits closer to capabilities of Java or TypeScript.
- pjmlp 5y agoIs writing a compiler, linker, kernel emulation layer, TCP/IP stack or a GPU debugger, systems programming?
- pornel 5y agoIf you dig deep enough into the Turing Tarpit, you can write these in JavaScript too (in fact, some of these have already been written). It's merely a disagreement about what the label "systems programming" should mean, rather than about capabilities and performance of the Go language. Objectively and undeniably Go relies on garbage collection, and C/C++/Rust don't. Google's implementation of Go prefers fast compilation speed over maximizing run-time efficiency, and C/C++/Rust implementations aim for zero-(runtime)cost abstractions. I hope it's clear there's no argument about the substantial technical differences between these languages. They have clearly different trade-offs, regardless of what name you think is appropriate to use for that difference.
- pjmlp 5y agoA disagreement indeed, https://people.inf.ethz.ch/wirth/ProjectOberon/Sources/Kernel.Mod.txt https://people.inf.ethz.ch/wirth/ProjectOberon/Sources/Kerne...
- pornel 5y agoI'm saying forks aren't for eating soup, and you're showing me soups eaten with a fork. In case of languages' general capabilities/applicability, I don't think singular counterexamples are sufficient, because they prove "can", rather than "should". Turing Tarpit means you can push languages way beyond their appropriate use-cases. There are also weird cases like Java smart cards and LISP machines, but I don't think it's useful to use these exceptions to classify Java and LISP as "assembly" or "machine" languages. Go does very well in the network services niche, but you can also write such network services in Bash (determined-enough people have written Bash HTTP servers). You can write small shell utilities in Go too. Does this mean Go and Bash are the same type of language? The lines are blurry, but you have to draw a line somewhere, otherwise every language is a shell scripting systems programming assembly machine language.
- ohYi55 5y agogit clone? I mean do we need bespoke package management tooling for everything now? Seems like an outdated systems admin meme that violates KISS, explodes dependency chains, risks security, etc. IT feels infected by sunk cost fallacy. It’s electron state in machines. The less altogether the better.
- mcronce 5y agoWhat, specifically, do you mean when you say Rust is "awful to work with"? With C and C++ I agree, but I've had a drastically better development experience in Rust than Go.
- svnpenn 5y agoYou should probably read the rest of the comment...
- mcronce 5y agoAre Result and Option really the only thing? Because nesting scopes based on Err/None is rarely the right choice, just like nesting a scope based on `if err == nil` isn't typically something you want to do in Go, or `if errno == 0` in C - You can panic trivially with `.unwrap()` - You can propagate the condition up trivially with `?` - `?` doesn't work with all types, but it does work with Option, and it does work with the vast majority of error types - making your custom error work with it is very easy (if you're whipping up an application or prototype and want your error handling very simple, `anyhow::Error` works great here) - You can convert None to an Err condition trivially with `.ok_or()?` - In cases where it makes sense, you can trivially use a default value with `.unwrap_or_default()` And all of these use require a _lot_ less code than `if err != nil { return nil, err }` And all of these allow you to use the Ok/Some value directly in a function call, or in a method chain, while still enabling the compiler to force you to handle the Err/None case The common theme here being "trivial" :) Result/Option are a big piece of that better developer experience.
- rastignack 5y agoHowever in typical rust code bases this systematic wrapping causes a lot of unhandled panics. Reading it feels just wrong.