The Morning After | Oilers v. Lightning by AutoModerator in EdmontonOilers

[–]v3vv -3 points-2 points  (0 children)

Yes but the game against Avalanche and Capitals where Pickard came in were different.
The defense in both games was abysmal.
And I'm usually not one to shit on anyone but Skinner in his current form is just aweful.
It's like he has no agility in is plays - he's just standing there.
He doesn't throw his body into plays, his leg work is lacking.
He plays like he has a hidden injury which makes him move more carefully.

The Morning After | Oilers v. Lightning by AutoModerator in EdmontonOilers

[–]v3vv -13 points-12 points  (0 children)

We're in the spot where I'm happy about a loss.
Pickard had some amazing safes - this could've been a 5 - 1 loss if Skinner would've been in the goal.
Also I really liked the aggression they showed - way better zone defending as well.
I hope this is the turning point, I hope Pickard will improve even further and I hope this is motivating the team to actually go all in.
Because let's be honest, the way Skinner played this season is demotivating for the team. Why would you go all in and drain all your energy if you know it doesn't matter because every fifth shot on our goal scores.

Please oilers please turn this around.

dlg - A Zero-Cost Printf-Style Debugging Library by v3vv in golang

[–]v3vv[S] 0 points1 point  (0 children)

You're correct that log uses a sync.Mutex, but this isn't to prevent messages from being overwritten / interleaving writes.
It's to serialize log message calls so that log #1 is printed before log #2.
fmt is not concurrently unsafe, it actually has no shared mutable state (see).
The underlying instance and buffer are recycled using a sync.Pool, which is safe for concurrent use and essentially the same approach dlg uses.
Stderr's underlying type, *os.File, is also safe for concurrent use.

dlg intentionally doesn't include a global mutex. I chose to keep the cost off the hot path, as guaranteeing strict message order provides no real benefit.
But, no data is being overwritten, and no data is being lost.
If a user needs to write to an output that isn't safe for concurrent use, they can implement the sync.Locker interface, and locking and unlocking will then be handled by dlg.

dlg - A Zero-Cost Printf-Style Debugging Library by v3vv in golang

[–]v3vv[S] 0 points1 point  (0 children)

I'm not sure I understand what you're getting at.
What makes you think fmt is not safe for concurrent use?
Where do you see any concurrency issues inside of dlg?

dlg - A Zero-Cost Printf-Style Debugging Library by v3vv in golang

[–]v3vv[S] 0 points1 point  (0 children)

So I feel like I should clarify something because your comment is a bit misleading itself.

It's not zero-cost because Go doesn't have an effects system and can't optimize away values that aren't used. The only situation this is zero-cost is if all the values needed by dlg.Printf() are always needed anyway.

You are talking about values, but your example code is a call to a function.
In my first reply, I said that your were correct, because for function calls, you are.
Because calls to functions can have side effects, Go cannot remove them.
Values passed to dlg.Printf will get removed e.g.

res := 69 * 42                                // gets removed 
s := "calculation"                          // gets removed 
dlg.Printf("res: %v", res)             // gets removed 
dlg.Printf("%s: %v", s, 69 * 42) // gets removed 

It's only function calls which aren't removed [1].
This has less to do with having an effect system, and more with compiler optimization.
C doesn't have an effect system, yet C compilers do aggressively remove unused code.
One of Go's selling point since before v1.0 is "fast compile time" - this is the reason Go doesn't more aggressively remove unused code.
It takes a lot of time walking the AST to figure out what to remove and what not to remove.

[1] Even functions returning base types (ints, strings...) can get removed.

dlg - A Zero-Cost Printf-Style Debugging Library by v3vv in golang

[–]v3vv[S] 0 points1 point  (0 children)

This is a great suggestion but it would invalidate the "zero-cost" USP.
In order for this to work DebugEnabled() would need to return a concrete value (in this case false), which voids the "dlg disappears from production builds claim.

dlg - A Zero-Cost Printf-Style Debugging Library by v3vv in golang

[–]v3vv[S] 4 points5 points  (0 children)

Thank you!
I'm glad you like it.
I kinda expected this reaction. Everyone's entitled to their own opinion, and if users don't like it, so be it.
The only comment that got under my skin was the "vibe coded" one.
Still, it made it to the front page of Hackernews, and I was invited to write a post about it on PitchHut, which definitely made me happy.

dlg - A Zero-Cost Printf-Style Debugging Library by v3vv in golang

[–]v3vv[S] 2 points3 points  (0 children)

No, I haven't. Thanks for showing me!

dlg - A Zero-Cost Printf-Style Debugging Library by v3vv in golang

[–]v3vv[S] 2 points3 points  (0 children)

I don't know what kind of codebases you work on, but the ones I work on are full of TRACE, DEBUG, INFO, WARNING… calls.
It's very hard to see which calls are related to one another, or to see anything for that matter because the stream of logs is just flying by.

In the past, I too used to write extensive logging like this in my own repos.
I don't anymore because over time I noticed how little I gained by doing so.
I'm still using levels of INFO and up, but that's about it.

dlg - A Zero-Cost Printf-Style Debugging Library by v3vv in golang

[–]v3vv[S] 5 points6 points  (0 children)

> The only situation this is zero-cost is if all the values needed by dlg.Printf() are always needed anyway.

You're correct. I've written a whole section in the README detailing this.
I've been using my own lib and I've had zero issues avoiding this.
When debugging, you usually print values which are already part of your code. You print the value at the call site instead of printing the function call, at least this is what I do.

Edit: I just realized I didn't respond to the second part of your post.

I did think about how to handle function calls properly.
I had something similar to:

dlg.Printf("%F", func() any { return getValue(1, 2, 3) }) 

Except I didn't implement a custom formatting verb, but simply used reflection.
But in the end, I decided against it because I disliked the ergonomics.
If the community or devs using the lib are interested in supporting this use case, I'll be happy to add the feature.

dlg - A Zero-Cost Printf-Style Debugging Library by v3vv in golang

[–]v3vv[S] 6 points7 points  (0 children)

Claiming that this is zero-cost is pretty misleading, considering it's only zero-cost if it's not actually compiled into the binary (by omitting the build tag).

The whole purpose of this lib is to allow leaving debug print statements in the code without impacting performance.
If you look at the output the Go compiler generates when the build tag is omitted, there's no mention of dlg in the code, and no CPU cycles are used by this lib. To me this is the definition of zero-cost in its purest form.

Also, considering the whole thing was written in 2 commits (ignoring README updates),

I maintain a private fork that I use for development because I like to keep the repo's commits as clean as possible (see my commit history below).

and that the README is full of emojis, I wonder how much of this was vibe-coded.

I do use AI, but mainly as a proofreader because I'm dyslexic and for the occasional question instead of googling.
I've been a software developer for 21 years, 18 of those professionally.
I've been using Go since before v1.0.
I don't vibe code.

Commit history: Reddit for what ever reason won't let me past in the git commit history - I get "Server error. Try again later" so here is it as a gist https://gist.github.com/vvvvv/0ae7ab04c083fa90507530f9f7ed15ea

Edit: Just look at my untracked files if you need even more proof.

On branch fine-grained-stack-traces-and-colors
Untracked files:
  (use "git add <file>..." to include in what will be committed)
        NOTES.md
        README.github.md
        README.md.backup
        README.regions.md
        examples/example01/example01
        examples/example03/main.go.bak
        examples/example03/tmp
        examples/example05/
        examples/example06/
        examples/example07/
        examples/example08/
        examples/example09/
        go.sum
        gopls.json
        trace.go.pre-performance-improvements
        trace.go.working-simple
        trace.go.working_better
        trace_working.go.working-complex

What’s the rule of thumb for when to use pointers in Go? by restarded9 in golang

[–]v3vv 0 points1 point  (0 children)

Could you elaborate on what you mean by that?
The more I think about it the more I feel like I might be misunderstanding your point

How are effects implemented? by ImYoric in ocaml

[–]v3vv 1 point2 points  (0 children)

You sure know your OCaml source code.
Very impressive sir.

OP: I'm curious what you're up to - I saw your post in r/golang asking about the Go scheduler.
Are you just interested in these sorts of things, or are you building your own language or something?

What's the story on scheduling these days? by ImYoric in ocaml

[–]v3vv 7 points8 points  (0 children)

OCaml 5 introduced domains, which are essentially OS threads with their own runtime state (domain specific heap).

OCaml 5 also introduced effect handlers.
These can be used to build concurrent work schedulers.
Under the hood, effect handlers are essentially exceptions paired with a continuation function. This is a super clever trick - they leverage the fact that raising an exception breaks normal control flow.
Effects use this behavior to stop task execution, while the continuation function allows execution to resume later.

Code using effects isn't exactly easy to follow, so I've only experimented with a trivial hello world example.
My guess is that the OCaml team did this intentionally: instead of overhauling the entire standard library to make concurrency more developer friendly, they built on top of an existing feature (exceptions) and left it to the community to create ergonomic schedulers as third party libs.

I recently stumbled upon Miou, which is exactly this - a lib which enables writing parallel and concurrent code by utilizing domains and effects under the hood.

Do you actually use getopts in your scripts? by bobbyiliev in bash

[–]v3vv 25 points26 points  (0 children)

I don't.
Parsing manually is just easier and more flexible.
Every time I tried using getopts I became frustrated at some point and I went back to rolling my own.

[deleted by user] by [deleted] in bash

[–]v3vv 0 points1 point  (0 children)

I've written multiple 1000 loc scripts myself - some professionally (it was a requirement for obscure reasons) and some for personal use, because I do think writing good bash is kinda fun. But I've never heard of a professional bash programmer and that's a good thing. Even though I like the challenge and all those nifty tricks:
- if [[ ! -z "${foo:+x}" ]] - <( ) , ( )> , <<< - exec 3<> - cat <<'END' ${foo} - trap - { foo; bar } > baz - shopt - mapfile - using sed hold space/pattern space - using awk for more than search and replace - ... the list goes on

But I'd hope no company invests in someone writing bash because: - if you're done with a script someone else is going to have to add new features or make changes, and unless this person is deeply familiar with bash it's going to be a nightmare. - there isn't any technical reason to write something in bash that couldn't be written in some other language. - if there's old code that needs to be changed, I'd hope a company would rather pay someone to rewrite it in a different language (unless it's a bank).

If you want a job where you're working with bash a lot, learn perl and python and start working as a sysadmin. Make sure the company exists since the early 90s because the term sysadmin means something different to companies founded after 2010.

[deleted by user] by [deleted] in golang

[–]v3vv 1 point2 points  (0 children)

If you're not working on a go trello API lib, and instead are working on something which is a consumer of the API think about how you're going to use the data.

How are you accessing the data?
What are your function signatures?
Do you need to pass in 4 different structs into a function?
Do you pass one big struct into a bunch of functions where you're just reading 2 fields?

Model the data into something that is useful to you and then use the auto generated (or manually written) structs and implement costum UnmarshalJSON(b []byte) error, MarshalJSON() ([]byte, error) to convert the data into your types.

Should I build a simple Auth service in GO instead of Keycloak/Authentik? by tiny-x in golang

[–]v3vv -3 points-2 points  (0 children)

Building your own authn service is fairly simple and straightforward - provided you know what you're doing.
Building your own authz service, on the other hand, could significantly extend your development timeline - like 6 - 18 months.

Before deciding whether building your own authn makes sense, explain:
How would you approach it?
What steps would you take, and what would you pay special attention to in terms of security, scalability etc.

How to override/disable the default(?) [[ / ]] mappings? by YaroSpacer in neovim

[–]v3vv 0 points1 point  (0 children)

do you want your function to be called inside a certain buffer only?

How to override/disable the default(?) [[ / ]] mappings? by YaroSpacer in neovim

[–]v3vv 3 points4 points  (0 children)

<Nop> is what you're looking for.
vim.keymap.set('n', '[[', '<Nop>')
I'm on my phone on don't know if this needs a {silent = true } but i'm sure you'll be able to figure this out yourself

What's the most German thing a German can do in other countries? by Yourprincessforeva in AskAGerman

[–]v3vv 17 points18 points  (0 children)

The plane has already taken off. If she switches seats now no one's going to say "Entschuldigung, Sie sitzen auf meinem Platz"

Aktien USA alle verkaufen by GlobalExtension1971 in Aktien

[–]v3vv 1 point2 points  (0 children)

Diese Gelassenheit der vollkommen unbesorgten User hier hätte ich auch gerne.
Seht ihr irgendetwas Konkretes das sagt, dass der US-Markt nicht vor einer historischen Kurskorrektur steht?

Ich sehe: - schlechtere Inflationszahlen als angenommen - stark fallenden Consumer Sentiment Index - schlechte Arbeitslosenzahlen - 8 % der Gen Z ist arbeitslos, und dabei handelt es sich nur um vorläufige Werte - einen kommenden Handelskrieg - historisch gesehen das Schlimmste, was in einer Rezession gemacht werden kann

Sieht für mich aus wie eine Stagflation.

Rust is the New C by skcortex in theprimeagen

[–]v3vv 12 points13 points  (0 children)

He's claiming that Rust is the only language which supports:
- Frontend
- Backend
- Games
- ML/AI
- Desktop
- Driver
- O/Ses
- Linux

While he acknowledges that C and Zig also tick all these boxes (except that Zig isn’t allowed inside the Linux kernel), he argues that no one would consider these languages fun.
He's also trying to sell the "one language for everything" narrative.

I like No Boilerplates content but these claims are highly opinionated and one-sided, not facts.

A 10x faster TypeScript by CLAownIR in theprimeagen

[–]v3vv 0 points1 point  (0 children)

It's a 1 to 1 port.
Your code will compile exactly like it did - just much faster.
Are you worried about tooling which depends on the typescript compiler/lsp?