On Wed, Jun 8, 2016 at 10:24 PM, Dan Callahan <
dan.ca...@gmail.com> wrote:
> Thoughts? Where should we go with this?
I think your bias somewhat shines through in the manner of your
reasoning, here. :) While I'm also biased, let me try to pivot your
thinking into a more objective line of reasoning, defining
(non-functional) requirements first and validating the options against
those later. The daemon:
1. Should run in a variety of environments
2. Should be easy to install in those environments
3. Should perform reasonably well
4. Needs some libraries (HTTP, crypto, email, key/value store)
5. Needs a low barrier of contribution
Going over these for Go and Rust, I would argue 1-3 are basically a
wash. Maybe cross-compiling is slightly more difficult for Rust, but
not dramatically so; if we just agree that it needs doing, it'll get
done. I totally agree that GC pauses won't have much of an impact for
this project. I think you're arguing that Go has more libraries and a
larger ecosystem. I don't disagree, but I also think that the Rust
ecosystem is large enough for our purposes, and quite vibrant itself.
As for low barrier of contribution, yes, more people know Go right
now. On the other hand, the Rust ecosystem is quite active. I think
you estimated 20-30 hours to build out a first version of the daemon
in Go, and you are at least somewhat familiar with Go. Without having
written more than hello, world in Rust before, I estimate that I spent
less than 30 hours on my version, suggesting it's not as inaccessible
as you might think. If you are put off by all the import lines,
remember that the import lines will make it very easy to find exactly
where some symbol is defined, which I find to be extremely helpful
when reading code.
I would argue there is one requirement you didn't mention explicitly
that I think is important, and that is robustness/reliability.
Especially because we're dealing with security-sensitive data, and
because we'd like to be internet-scale, I think robustness is pretty
important to this project. It is my feeling that Rust wins out over Go
here, because this is exactly what it was designed for. The strict
type system makes it so that successful compilation almost always
means code that does the right thing. The amount of unwrap calls in my
prototype may look unwieldy, they also provide very obvious markers
where we need some error handling, and if we replace these calls with
proper error handling, I think we can be very confident indeed in the
robustness/reliability of the Rust daemon. (Having no Go experience, I
don't know how it does error handling exactly; but my impression from
what I've read is that it's quite a bit easier to leave mistakes in
it.)
For me, the daemon prototype was a good project for learning Rust.
Having learned it, I've found myself immediately wanting to use it
more. I don't mind if the community prefers a Go implementation; in
that case, my implementation can either just linger or be an
alternative implementation. Personally I don't think I will contribute
much to a Go implementation, just because I'm not interested in Go as
a language.
Finally, I would argue that, at a meta level, this community doesn't
seem to have a large amount of resources at its disposal. Because I
was intrinsically motivated to build a Rust version, and not a Go
version. Even if, based on the requirements we've described so far, I
argue that Rust is better, and you argue Go is better, I think we can
agree that the difference is not very large at all. If you're
motivated now by having a production version of the daemon, it would
be more efficient to spend a few hours with this Rust code rather than
spending (probably) more hours on building it again in Go.
Still, I'm clearly biased, and I don't want to force the community to
go in any particular direction. If the rest of the you think Go is the
better option, you should definitely go for it.
Cheers,
Dirkjan