Live data from Hacker News

Rust and Go

medium.com

31–40 of 311 posts

Re: Rust and Go

#31
It's not clear how much experience the author really acquired with each language, and whether that experience was sufficient experience to justify his statement:

Go felt that way to me — it was good at everything, but nothing grabbed me and made me feel excited in a way I wasn’t already about something else in my ecosystem.

He's apparently using each language to write relatively small command-line utilities. If Go is "amazing" at anything, its usually cited as a language of choice for (1) networked systems, and (2) large yet maintainable systems. I'm not sure his initial foray into the language would have provided enough experience to accurately assess those merits one way or the other.

Rob Pike once expressed surprise that people migrating to Go weren't C++ programmers, but Ruby/Python/etc. programmers who needed more performance. That leads you to wonder: (EDIT: removed pejoratives) if a programmer desired to switch from C/C++ to another language but hasn't by now, why not?

1. They require the performance benefits of C/C++ (and as humanrebar pointed out, manual memory management).

2. They're tied to legacy code, with too little incentive to switch.

3. They have an organizational mandate.

Any programmer who wasn't subject to the above constraints and wanted to switch could have done so before Go showed up on the scene. And if a programmer uses C or C++ solely because the above constraints, Go isn't likely to change that.

Rust may have a better chance of converting C++ programmers, if it offers the performance and control demanded by programmers who are using C++ by necessity. It will be interesting to see if people migrating from Python/Ruby to a higher performance language will choose Go or Rust in the future. Kind of like the OP, I like Go but I'm excited about Rust.

Re: Rust and Go

#32
post #22

Earlier quoted context omitted.

There are a lot of comments in that thread, is there anything specific you think stands out? Some of Ian's initial comments were saying that they are being very very careful about what gets added to the language. Also, at this point the language syntax itself is basically locked. And from everything I've seen, they are focusing more on the runtime and tooling before they make any serious changes to the code language.

I'm thinking of the crowd that insists "map" is never more useful or readable than s straight for-loop. So not only don't they want it in go (which could be understandable in some situations), they genuinely seem to think it has no place in an imperative language. That blows my mind.

I've written in both paradigms and I mostly agree with the Go team. That it blows your mind blows mine, and I suppose it's good that we have these choices so we don't have to agree.

Could you show me a code snippet of maps and filters used that you believe is more readable than for loops? Maybe I'll get a laugh out of that. :)

Re: Rust and Go

#33

If you are considering Go, or just want a good laugh, just read discussions where higher order functions are discussed. Or for that matter, generics. Here is a gem: https://groups.google.com/forum/#!topic/golang-nuts/RKymTuSC... There's a chance you'll laugh at the people dismissing higher order functions as nonsense, in which case Go might not be for you. This is a good test of whether you want to try it out or not.

Wow that makes me cringe. This specifically:

> The power of the map/filter abstraction starts becoming more apparent when you do things like

> Filter(someFunc, Map(funcWith3args, vecA, vecB, vecC))

> And you realize you should swap map and filter for your particular app for better performance.

met with this reply:

> vs > [10 lines of code for two for loops doing the same thing] > Using range makes it obvious that there is a performance hit in the first place.

Re: Rust and Go

#34
post #27

I think to properly write a language comparison, you need to have extensively used both languages and with multiple use cases. For example: I've recently attempted writing a small service in Go and it only took a few hours for me to figure out how weak a language could be without some sort of type-abstraction or generics: I had to implement a FindValueInArray() twice for two different types. This should be a big issu…

I'm confused by your comment. Does it take extensive experience and multiple use cases to assess a language? Or a couple hours writing a small service?

Re: Rust and Go

#35
Not a bad write-up. The Rust code snippets can be slimmed down very slightly though. Here's main():

    fn main() {
        let args = os::args();
        let washed_args = args.iter().map(|arg| arg.as_slice()).collect::>();
        match washed_args.as_slice() {
            [_, "review", opts..] => review(opts),
            _ => usage()
        }
    }
although I might actually suggest the alternative approach:

    fn main() {
        let mut args = os::args().into_iter();
        args.next(); // skip program name
        match args.next().map(|s| s.as_slice()) {
            Some("review") => review(args.collect::>()),
            _ => usage()
        }
    }
(this approach requires `review()` to take a `Vec` instead of a `&[&str]`, but that's not a difficult change, and we could fix it using a second line of code if we wanted but at the cost of introducing a new allocation, like the original code does)

For review() I'd suggest changing the original code:

    let cwd = os::getcwd();
    let have_dot_git = have_dot_git(cwd.clone());

    let dot_git_dir: &Path = match have_dot_git.as_ref() {
        Some(path) => path,
        None => { panic!("{} does not appear to have a controlling .git directory; you are not in a git repository!", cwd.display()) },
    };
to the following:

    let cwd = os::getcwd();
    let dot_git_dir = have_dot_git(&cwd).expect(format!("{} does not appear to have a controlling .git directory; you are not in a git repository!", cwd.display()).as_slice());
This actually leaves `dot_git_dir` as a `Path` instead of a `&Path`, but I think that's better anyway. It also requires `have_dot_git()` to take a `&Path` instead of (what I assume it takes now,) a `Path`, which is an appropriate change as there's no need for cloning the path.

Re: Rust and Go

#36
post #35

Not a bad write-up. The Rust code snippets can be slimmed down very slightly though. Here's main(): fn main() { let args = os::args(); let washed_args = args.iter().map(|arg| arg.as_slice()).collect:: >(); match washed_args.as_slice() { [_, "review", opts..] => review(opts), _ => usage() } } although I might actually suggest the alternative approach: fn main() { let mut args = os::args().into_iter(); args.next(); //…

It's also worth pointing out that if you enable the `slicing_syntax` feature gate then all the `.as_slice()` calls can turn into the suffix operator `[]`.

Re: Rust and Go

#37

If you are considering Go, or just want a good laugh, just read discussions where higher order functions are discussed. Or for that matter, generics. Here is a gem: https://groups.google.com/forum/#!topic/golang-nuts/RKymTuSC... There's a chance you'll laugh at the people dismissing higher order functions as nonsense, in which case Go might not be for you. This is a good test of whether you want to try it out or not.

What an infuriating thread. I guess I'm not the kind of person Go is made for, but the fact that everyone in the thread was so close-minded about what might be helpful about map, filter, and reduce was frankly absurd.

I especially enjoyed the demonstration of map would look in Go code, complete with a useless anonymous function:

> bar = map(foo, func(e T) { return f(e) })

And this guy who doesn't seem to understand the concept of function pointers:

> You seem to equate the function f with a single character, which it's not. The user must write it's implementation, which you have omitted for your own benefit.

Re: Rust and Go

#38
post #22

Earlier quoted context omitted.

There are a lot of comments in that thread, is there anything specific you think stands out? Some of Ian's initial comments were saying that they are being very very careful about what gets added to the language. Also, at this point the language syntax itself is basically locked. And from everything I've seen, they are focusing more on the runtime and tooling before they make any serious changes to the code language.

I'm thinking of the crowd that insists "map" is never more useful or readable than s straight for-loop. So not only don't they want it in go (which could be understandable in some situations), they genuinely seem to think it has no place in an imperative language. That blows my mind.

I don't get the sense that they think it has no place in an imperative language. Like the OP calls out, Go is a very small language with few constructs. For a lot of tasks there are simply only one way to do things. Some would consider this a strength, others a weakness (kind of like Python vs. Perl).

Re: Rust and Go

#40
post #23

The article is a lightweight analysis by someone who writes small programs. He does get that, for Rust, "If the compiler accepted my input, it ran — fast and correctly. Period." That's was a common experience with the very tight languages, such as Ada and the various Modulas. It's been a while since a language that tight was mainstream. We need one now, badly. Go isn't bad for writing routine server-side web stuff th…

I could not agree more with your first paragraph. The only other language I've used that I've had that experience with was Haskell, and while there are good arguments to be made for using Haskell in production, it should be obvious that's not a language that will ever become mainstream.

I'm hoping that as Swift evolves over time, it will slowly become that sort of language. Right now it's pretty hard to write any real-world code in Swift that doesn't work with the Cocoa frameworks, and the Cocoa frameworks are typed in an objective-c-compatible way (even if new frameworks are written in Swift they'll need to maintain obj-c compatibility), which means you don't get the strong typing that's necessary for this property. Pure Swift code has the potential to behave like this, although you probably need to avoid the ImplicitlyUnwrappedOptional feature (the ! suffix on types), which of course primarily exists for ease of obj-c integration anyway.

I'm bringing up Swift because, with Apple's backing, it's very quickly becoming a "mainstream" language. I put that in quotes because it is only usable with iOS and OS X programming (for now at least), but iOS is large enough that obj-c should be considered a mainstream language despite the fact that almost nobody outside of iOS/OS X uses it, and therefore as Swift supplants obj-c it becomes appropriate to call it mainstream.

Regarding parallelism, I've been in love with Rust for a long time now, and one of the biggest reasons is because Rust makes parallelism safe. As an iOS/OS X programmer by trade, I think thread safety is far and away the biggest elephant in the room. Despite the fact that we've known that multithreading is the future for years, and despite the wonderful Grand Central Dispatch library on iOS/OS X, most programmers still think in a single-threaded mindset and don't even consider how their code should operate if invoked on a separate thread. This was one of my bugaboos with Go back when I was using that language (which was from the day it was announced right up until I discovered Rust, though admittedly my usage was in hobby projects and nothing serious).

I applaud the fact that Go has a data race detector now, which I used to finally uncover a lurking data race that plagued one of my programs for months (and which was ultimately caused by the Go library using two goroutines where I expected one, and therefore data which I expected to be on a single goroutine was actually mutated from two goroutines simultaneously). But I think Rust is absolute proof that a modern language can be designed such that data races are prohibited at compile-time without sacrificing any language flexibility.

Post reply on HN