Article on Go

This commit is contained in:
Araozu 2024-05-25 20:44:27 -05:00
parent d6da4f15f4
commit 30acaf936d
7 changed files with 243 additions and 4 deletions

View File

@ -4,5 +4,13 @@ import tailwind from "@astrojs/tailwind";
// https://astro.build/config
export default defineConfig({
integrations: [tailwind()]
integrations: [tailwind()],
markdown: {
shikiConfig: {
themes: {
light: "catppuccin-latte",
dark: "github-dark"
},
},
},
});

View File

@ -15,5 +15,8 @@
"astro": "^4.6.1",
"tailwindcss": "^3.4.3",
"typescript": "^5.4.5"
},
"devDependencies": {
"@shikijs/transformers": "^1.6.0"
}
}

View File

@ -23,6 +23,10 @@ importers:
typescript:
specifier: ^5.4.5
version: 5.4.5
devDependencies:
'@shikijs/transformers':
specifier: ^1.6.0
version: 1.6.0
packages:
@ -588,6 +592,12 @@ packages:
'@shikijs/core@1.3.0':
resolution: {integrity: sha512-7fedsBfuILDTBmrYZNFI8B6ATTxhQAasUHllHmjvSZPnoq4bULWoTpHwmuQvZ8Aq03/tAa2IGo6RXqWtHdWaCA==}
'@shikijs/core@1.6.0':
resolution: {integrity: sha512-NIEAi5U5R7BLkbW1pG/ZKu3eb1lzc3/+jD0lFsuxMT7zjaf9bbNwdNyMr7zh/Zl8EXQtQ+MYBAt5G+JLu+5DlA==}
'@shikijs/transformers@1.6.0':
resolution: {integrity: sha512-qGfHe1ECiqfE2STPWvfogIj/9Q0SK+MCRJdoITkW7AmFuB7DmbFnBT2US84+zklJOB51MzNO8RUXZiauWssJlQ==}
'@types/babel__core@7.20.5':
resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
@ -1833,6 +1843,9 @@ packages:
shiki@1.3.0:
resolution: {integrity: sha512-9aNdQy/etMXctnPzsje1h1XIGm9YfRcSksKOGqZWXA/qP9G18/8fpz5Bjpma8bOgz3tqIpjERAd6/lLjFyzoww==}
shiki@1.6.0:
resolution: {integrity: sha512-P31ROeXcVgW/k3Z+vUUErcxoTah7ZRaimctOpzGuqAntqnnSmx1HOsvnbAB8Z2qfXPRhw61yptAzCsuKOhTHwQ==}
signal-exit@3.0.7:
resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==}
@ -2746,6 +2759,12 @@ snapshots:
'@shikijs/core@1.3.0': {}
'@shikijs/core@1.6.0': {}
'@shikijs/transformers@1.6.0':
dependencies:
shiki: 1.6.0
'@types/babel__core@7.20.5':
dependencies:
'@babel/parser': 7.24.4
@ -4383,6 +4402,10 @@ snapshots:
dependencies:
'@shikijs/core': 1.3.0
shiki@1.6.0:
dependencies:
'@shikijs/core': 1.6.0
signal-exit@3.0.7: {}
signal-exit@4.1.0: {}

View File

@ -1,11 +1,32 @@
#blog code {
:not(pre)>code {
font-family: "Iosevka Fixed Web", Iosevka, monospace;
border: solid 1px var(--c-on-bg);
border: solid 1px var(--c-border-2);
padding: 0 0.25rem;
border-radius: 0.25rem;
}
pre.astro-code {
padding: 1rem;
border-radius: 0.5rem;
border: solid 1px var(--c-border-1);
font-size: 0.9rem;
}
pre.astro-code>code {
counter-reset: step;
counter-increment: step 0;
}
pre.astro-code>code .line::before {
content: counter(step);
counter-increment: step;
width: 1rem;
margin-right: 1.5rem;
display: inline-block;
text-align: right;
color: rgba(115, 138, 148, .4)
}
#blog p {
margin: 1rem 0;
}
@ -27,3 +48,16 @@
text-decoration: underline;
color: #3b82f6;
}
@media (prefers-color-scheme: dark) {
.astro-code,
.astro-code span {
color: var(--shiki-dark) !important;
background-color: var(--shiki-dark-bg) !important;
/* Optional, if you also want font styles */
font-style: var(--shiki-dark-font-style) !important;
font-weight: var(--shiki-dark-font-weight) !important;
text-decoration: var(--shiki-dark-text-decoration) !important;
}
}

View File

@ -31,6 +31,8 @@
--c-on-bg: #dedede;
--c-bg-2: #18181b;
--c-border-1: transparent;
--c-border-2: #606060;
}
@media (prefers-color-scheme: light) {
@ -39,6 +41,8 @@
--c-on-bg: #101010;
--c-bg-2: white;
--c-border-1: #aaaaaa;
--c-border-2: #aaaaaa;
}
}

162
src/pages/blog/go-1.md Normal file
View File

@ -0,0 +1,162 @@
---
layout: ../../layouts/BlogLayout.astro
title: Golang first impressions
description: First thoughts after using a little bit of Golang
pubDate: "2024-05-25"
tags: ["programming", "golang", "rust", "short"]
image:
url: ""
alt: ""
caption: ""
---
I've been trying out Golang for a few days, and here are some thoughts
I have about it.
And by a few days I mean that I've solved AoC until day 11 (I think),
and I'm writing a game backend that communicates via JSON/WebSockets
to a web frontend.
## Irrelevant background
I don't remember where did I hear about Golang first. But I clearly
remember that my first opinion of it was heavily influenced by fasterthanlime
posts about it. I think I discovered his page with his "I want off Mr. Golang's
wild ride" and "Lies we tell to ourselves to keep using Golang" posts.
So, I had a negative impression about it for some time. And at the time I
was felling in love with Rust, which Amos uses as a comparison point,
so all the arguments made sense, and I did what any reasonable person on the
internet would do: I made his arguments mine :)
Then, another tech-fluencer I follow began to talk about Golang. ThePrimeagen.
And apparently he liked Golang a lot. He was (and I think still is at the
time of writing) learning
Golang, and was happy to try it out. So I did what any reasonable person on
the internet would do: I made his opinions mine :)
And so, I decided to try out Golang, coming from having learned a lot of Rust.
## A nicer C + gc
My very first impression was that it felt a lot like C. Very imperative code,
very simple, very minimalist. You can't even do something like `"hello".length`,
you do `len("hello")`, in a very C-style. However, you don't have to manually
manage all your memory, since Golang is garbage collected. So, it feels like a
nicer C.
## Confusion with references
I think that Rust messed up with the way that I think about
references/parameters/pass-by-value/pass-by-reference.
First, in Java and JS I got used that anything that is not a primitive
datatype is passed by reference. Since neither of these use pointers, that's
reasonable.
Then, in Rust, you define instead ownership, lifetimes and references. So, I
got used to:
```rust
fn test_function<'a>(
a: Type,
b: mut Type,
c: &Type,
d: &mut Type,
e: &'a Type,
f: &'a mut Type,
) {
// ...
}
```
Which are, off the top of my head:
- a: Take ownership of `Type`
- b: Take ownership of a mutable `Type`
- c: A reference to `Type`
- d: A mutable reference to `Type`
- e: A reference to `Type` with lifetime `'a`
- f: A mutable reference to `Type` with lifetime `'a`
I got used to pass-by-refernce, in one way or another.
So, I came to Golang expecting the same. Primitive types are passed by value,
complex types are passed by reference. But apparently they aren't, which had
me scratching my head for many hours.
I had a function that took a struct, modified some values, and returned.
```go
// Some hypothetical code
type Node struct {
Value string
Visited bool
}
func mark_as_visited(node Node) {
// ...
node.Visited = true
// ...
}
```
Apparently, this will create a copy of `Node` instead of mutating the parameter.
So Golang doesn't have automaty pass-by-reference, only pass-by-value. Which
mimics the way C works, but in my limited experience with C I was always using
pointers due to `malloc` and friends, so I never noticed. Skill issue.
But still, for a garbage collected language, I was expecting it to behave like
other garbage collected languages. (And now I wonder if Go is garbage collected,
and you can't do pointer arithmetic, why do you have access to pointers?)
## if err != nil
I wish Go had some amount of syntax for error handling. `if err != nil` feels
verbose, but it's not bad. What I'm confused about still is why it's all
`error`, instead of having different error types? I guess I got used to Rust.
Still, errors as values are the best way to do error handling.
## nil
It's 2024 and we still have `nil` pointer exceptions. I think it's a huge
mistep to not have some form of nullable types. Something like `int?` that
clearly communicates that the value can be `nil`, and more importantly,
that forces you to explicitly check for it. Kotlin, Rust, Zig, Nim and
almost every modern language have it.
And being relatively "low-level" or having a runtime penalty is not an excuse
because a) Go is not "low-level" b) Go ships a gc and runtime with every binary
c) Zig is "low-level" and still has nullable types.
## zero values
Altough zero values have not caused problems for me (yet), I can definitely see
how they are bad. Just having a struct that contains a pointer to other struct
can potentially cause a NPE, and the compiler doesn't do anything about it.
Yes, it's a skill issue to not check in every single place structs are used.
And by that logic, it's a skill issue to not program in punch cards and use
modern languages. smh.
## devtools
The devtools are (as far as my limited used goes) really, really good. The
language server is fast, I love the fast, opinionated, on save code formatter
(better than rust analyzer & cargo fmt) and the package manager is good.
## conclusions
So in conclusion, I'm still learning Go. I'm not at the level that
the things that Amos complains about are problems for me. But insofar, the
language itself is, to me, inferior to Rust. Still good, but not as good
as Rust in every aspect.

View File

@ -17,5 +17,10 @@ import BlogLayout from "../../layouts/BlogLayout.astro";
The responsible stack
</a>
</li>
<li>
<a class="underline" href="/blog/go-1/">
Golang first impressions
</a>
</li>
</ul>
</BlogLayout>