Article on Go
This commit is contained in:
parent
d6da4f15f4
commit
30acaf936d
@ -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"
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -15,5 +15,8 @@
|
||||
"astro": "^4.6.1",
|
||||
"tailwindcss": "^3.4.3",
|
||||
"typescript": "^5.4.5"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@shikijs/transformers": "^1.6.0"
|
||||
}
|
||||
}
|
||||
|
@ -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: {}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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
162
src/pages/blog/go-1.md
Normal 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.
|
||||
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user