More stuff
This commit is contained in:
parent
4b67ef3b9d
commit
19b67010cc
4 changed files with 94 additions and 24 deletions
9
content/blog/contributor-license-agreements.md
Normal file
9
content/blog/contributor-license-agreements.md
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
title: "Contributor License Agreements"
|
||||
date: "2024-06-12"
|
||||
draft: true
|
||||
---
|
||||
|
||||
# Other interesting points on CLAs:
|
||||
|
||||
- Some people cannot contribute when CLAs are in the way because they cannot give out "perpetual" or "unrestricted" licenses to their work due to agreements with their own employer or place of education: https://utcc.utoronto.ca/~cks/space/blog/tech/CLAsImpedeContributions
|
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
title: "iex and dbg/1 without pry prompts"
|
||||
title: "Rust vs. Go"
|
||||
date: "2024-06-06"
|
||||
draft: true
|
||||
---
|
||||
|
@ -22,8 +22,8 @@ preferences. I have roughly-equivalent Rust experience, exposure, and knowledge
|
|||
than I do Golang, though I have run, operated, and maintained far more Golang
|
||||
services at my job than I have Rust.
|
||||
|
||||
Also by posting this I'm sure I will get free consultancy on my Go code and help
|
||||
me be a better programmer! 😜
|
||||
Also by posting this I'm sure I will get free <s>flame wars</s> consultation on
|
||||
my Go code and become a better programmer! 😜
|
||||
|
||||
## Stop Comparing! They're Different!
|
||||
|
||||
|
@ -31,39 +31,56 @@ Of course they are! This doesn't mean they can't be used to solve the same
|
|||
problems. In my experience, one is simply better than the other for the same
|
||||
use-cases.
|
||||
|
||||
They're also the same _category_ of thing: general purpose programming
|
||||
languages. Which means it's good to talk about the various strengths and
|
||||
weaknesses of the two.
|
||||
|
||||
# Why Rust
|
||||
|
||||
## Rust has _all_ of Go's superpowers
|
||||
|
||||
Ok, except it's uber simplicity. But what you lose in simplicity, you gain in
|
||||
many other areas. I'll elaborate later.
|
||||
|
||||
### Goroutines
|
||||
|
||||
Use `tokio::spawn`. Yes, they are different (mainly stackless versus
|
||||
stackful) but the goal and considerations are effectively the same.
|
||||
|
||||
If you don't like Tokio or can't use it, there are different implementations of
|
||||
this on top of Rust's `async/await` system that have the same benefits.
|
||||
|
||||
While it's arguably not as cohesive as Go's implementation, it's there if you
|
||||
want it.
|
||||
|
||||
### Channels
|
||||
|
||||
Use `std::sync::mpsc`.
|
||||
Rust has these. See `std::sync::mpsc`.
|
||||
|
||||
### Defer
|
||||
|
||||
Largely unnecessary thanks to the compiler, but you can implement your
|
||||
own via the `Drop` trait or reach for `scopeguard`.
|
||||
own via the `Drop` trait or reach for the `scopeguard` crate.
|
||||
|
||||
### Tooling
|
||||
|
||||
Again, Rust has an incredible tools ecosystem just like Go. Better in many ways
|
||||
since many tools considered "necessary" for modern and idiomatic Go are simply
|
||||
are not so for Rust, such as code generation. Such needs are instead fulfilled
|
||||
by metaprogramming (macros).
|
||||
since many tools considered _necessary_ for modern and idiomatic Go are simply
|
||||
not for Rust, such as code generation tools. Such needs are instead fulfilled by
|
||||
metaprogramming (macros) instead.
|
||||
|
||||
### Explicit error handling
|
||||
|
||||
Hahaha!
|
||||
Haha! I guess I'm the four-millionth person to write about how awful `if err !
|
||||
= nil` is, but seriously, Rust's `?` operator and pattern matching abilities are
|
||||
so fantastic.
|
||||
|
||||
You're gonna _love_ Rust in comparison.
|
||||
|
||||
## Rust is expressive
|
||||
|
||||
Now we're getting to some of the things Rust is simply better than Go at.
|
||||
|
||||
Being expressive has downsides. A common question I'll find myself asking is
|
||||
"Which of these four ways is the _best_ way to do this?"
|
||||
|
||||
|
@ -72,38 +89,57 @@ _more_ than be stuck with Go's simplicity.
|
|||
|
||||
## Rust code has fewer bugs
|
||||
|
||||
Obviously this is factually incorrect. However, I simply write my code in Rust
|
||||
and when it compiles it works as I intended. Rust code and the compiler make it
|
||||
much more difficult to represent invalid states.
|
||||
Obviously this isn't entirely a fair thing to say, but it is true that Rust
|
||||
simply makes it incredibly difficult (effectively impossible?) to have certain
|
||||
kinds of bugs in your code as opposed to Go.
|
||||
|
||||
Meanwhile Go code has nil checks, pointers, implicit interfaces, and a few other
|
||||
things you will inevitably run into.
|
||||
I simply write my code in Rust and when it compiles it works as I intended.
|
||||
Rust code and the compiler make it much more difficult to represent invalid
|
||||
states.
|
||||
|
||||
Meanwhile Go code has nil checks, implicit interfaces, and a few other things
|
||||
you will inevitably run into.
|
||||
|
||||
That said, Go's tooling has been improving a _lot_ around this in my opinion;
|
||||
`golangci-lint` is awesome.
|
||||
`golangci-lint` is awesome and shores up much of these issues.
|
||||
|
||||
## Inline tests
|
||||
|
||||
I strongly dislike being required to put my unit tests in separate files. Call
|
||||
me crazy, but having the tests in the same file is something I find appealing.
|
||||
|
||||
Also
|
||||
[doctests](https://doc.rust-lang.org/rustdoc/write-documentation/documentation-tests.html).
|
||||
The best kind of inline test. Gotta have 'em.
|
||||
|
||||
## Modules and dependencies
|
||||
|
||||
Go's module system got bolted on a little late and suffers from the Google
|
||||
monorepo assumptions/expectations situation. In some ways, this is actually
|
||||
very cool. In many ways, though, it's pretty annoying.
|
||||
very cool. In many ways, though, it's pretty annoying. These days, if you follow
|
||||
the "modern" path, things can work great.
|
||||
|
||||
Rust has its own issues with Cargo and its ties to GitHub, but even those can be
|
||||
worked around if you like.
|
||||
|
||||
Rust also has issues with MSRV "promises" being largely unenforceable due to
|
||||
Cargo lockfiles not being `--locked` by default. This is pretty mind-boggling
|
||||
to me. Could also be a skill issue.
|
||||
Overall, Rust has a more familiar and approachable module system.
|
||||
|
||||
## Making Changes
|
||||
|
||||
When you change a hunk of Go code, you can't know for sure what else in the code
|
||||
may need to change as a result. If you add a field to a struct, you may need to
|
||||
find the places you are building that struct and update the code and hopefully
|
||||
you don't miss a spot.
|
||||
|
||||
Rust makes changing an existing codebase less scary. It will tell you pretty
|
||||
much everywhere you need to go and change other things as a result of your small
|
||||
change. It totally changes the way you modify software.
|
||||
|
||||
## Documentation
|
||||
|
||||
Rust's standard library and popular crates' documentation is _generally_ much
|
||||
better than Go's. Doctests and examples are common.
|
||||
better than Go's. Doctests are wonderful and examples are more common in Rust
|
||||
crates than in Go modules.
|
||||
|
||||
## Macros
|
||||
|
||||
|
@ -112,6 +148,14 @@ slower. Yes, they can do awful stuff.
|
|||
|
||||
So does Go codegen.
|
||||
|
||||
But being able to derive implementations and affect them with attributes is
|
||||
really phenomenal. Especially if you mess with something like `bevy` or `axum`.
|
||||
|
||||
## Traits
|
||||
|
||||
Rust forces you the implement a trait explicitly while Go does not. It's a small
|
||||
thing, but this again lets the code communicate the intent of the programmer.
|
||||
|
||||
## No surprises
|
||||
|
||||
Nothing that executes before `main()` while Go has freakin' `init()` and of
|
||||
|
@ -337,6 +381,14 @@ Go has a big standard library and just includes a ton of stuff. I wish Rust had
|
|||
something similar for "blessed" "core" crates. I understand the standard library
|
||||
for a systems-level language must be small, but that's how I feel.
|
||||
|
||||
### Other Builtins
|
||||
|
||||
Go can kind of manage its own versions and everything and you pretty much just
|
||||
do `go whatever` and get on with your life.
|
||||
|
||||
With Rust, you need to learn a couple different tools (but mainly just `cargo`)
|
||||
such as `rustup`.
|
||||
|
||||
## Go is Simple
|
||||
|
||||
It's easy to get caught up trying to do things in Rust the "right" way and work
|
||||
|
@ -345,7 +397,8 @@ computer science puzzle that the compiler presents to you.
|
|||
|
||||
In Go, that is simply less true. You will do the obvious thing at perhaps some
|
||||
slight performance cost and get back to implementing your feature and shipping
|
||||
code.
|
||||
code. It's almost always going to be perfectly sufficient and generally easy to
|
||||
come back to and understand.
|
||||
|
||||
## Go Compilation Speed
|
||||
|
||||
|
@ -367,3 +420,9 @@ With Rust, you _do_ have to think about `--release` performance -- such as when
|
|||
writing Leetcode solutions against your friends.
|
||||
|
||||
I'm getting nitpicky here, but... it's my article.
|
||||
|
||||
## Versioning
|
||||
|
||||
Rust has issues with MSRV "promises" being largely unenforceable due to Cargo
|
||||
lockfiles not being `--locked` by default. This is pretty mind-boggling to me.
|
||||
Could also be a skill issue.
|
|
@ -1,4 +1,4 @@
|
|||
<div class="left-border">
|
||||
<p class="left-border">
|
||||
<h3>
|
||||
<a style="flex-shrink: 1; margin-right: auto;" href="{{ .Permalink }}">
|
||||
{{ .Title }}
|
||||
|
@ -7,4 +7,4 @@
|
|||
<small>Posted on {{ dateFormat "Jan 2 2006" (cond .Date.IsZero .Lastmod .Date) }}</small>
|
||||
</h3>
|
||||
{{ .Summary }}
|
||||
</div>
|
||||
</p>
|
||||
|
|
|
@ -51,9 +51,11 @@ details > summary::-webkit-details-marker
|
|||
|
||||
details > summary::after
|
||||
position absolute
|
||||
padding 0 1em
|
||||
top 0
|
||||
right -1em
|
||||
background-image url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='1.5' stroke='currentColor' style='width: 1em; height: 1em;'><path stroke-linecap='round' stroke-linejoin='round' d='M12 9v6m3-3H9m12 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z' /></svg>")
|
||||
// background-image url("data:image/svg+xml,<svg xmlns='http://www.w3.org/2000/svg' fill='none' viewBox='0 0 24 24' stroke-width='1.5' stroke='currentColor' style='width: 1em; height: 1em;'><path stroke-linecap='round' stroke-linejoin='round' d='M12 9v6m3-3H9m12 0a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z' /></svg>")
|
||||
content "+"
|
||||
|
||||
details[open] > summary::after
|
||||
content "-"
|
||||
|
|
Loading…
Reference in a new issue