HNHacker News
TopNewBestAskShowJobs

bheadmaster

5,648 karma · joined March 31, 2021

just some random guy on the internet
submissionscomments
bheadmaster··on Calibre 8.0
No, the issue is:

> without explicitly being asked to do so

You may argue that if you're installing Calibre, you want document file types to be associated with it, but it'd still be nicer if the user was given an option not to do that in the installer itself, instead of just overwriting whatever other file type associations user has had.

bheadmaster··on Crew-9 Returns to Earth
Just because they signed up for it, doesn't mean we shouldn't try our best to prevent it. Staying for 9 months in space is not a small deal for people's health.
bheadmaster··on Crew-9 Returns to Earth
That does not make sense.

Did they care more about "not manipulating NASA for political points" than about astronauts who were stuck in space for 9 months, with all the harmful effects that it entails?

bheadmaster··on Crew-9 Returns to Earth
In a situation where everyone has an incentive to lie, there's no reason to believe anyone.

Musk and Trump have a history of exaggarating, to say it lightly, but NASA, like most of the government entities, hasn't been transparent with their internal processes either.

I see no reason to trust either of them.

bheadmaster··on Crew-9 Returns to Earth
What do you mean? The fact that they didn't return the astronauts implies the last administration's integrity?
bheadmaster··on Crew-9 Returns to Earth
I wasn't very convinced by his arguments - the main one being:

    Senior NASA officials earlier this month confirmed, publicly and on the record, that the decision was made by the space agency in the best interests of the International Space Station Program. Not for political reasons.
To be a little snarky here - so Senior NASA officials: honest, Musk: liar?

If, hypothetically, NASA was pressured for political reasons, I don't think Senior NASA officials would reveal it to the public anyway. So the fact that they said it's not for political reasons doesn't really prove anything for either side of the argument.

bheadmaster··on HTTP/3 is everywhere but nowhere
> StackOverflow survey[0] shows C# (27.1%) right behind Java (30.3%)

Can we rule out sample bias here? After all, Jon Skeet [0] is an important part of the Stack Overflow's C# community.

It might just be the case that C# and Java developers use Stack Overflow more than users of other languages.

[0] https://toggl.com/blog/save-princess-8-programming-languages

bheadmaster··on HTTP/3 is everywhere but nowhere
Native AOT compilation is definitely not the same as self-contained package. With that logic, every Docker container could be considered AOT compiled static executable.
bheadmaster··on Xdg-ninja: checking your $HOME for unwanted files and directories
> This is the crap responsible for poluting $HOME.

I think people who wrote software used $HOME for dotfiles way before XDG even existed.

> If the user does not configure anything, just use global defaults.

And if he does, where do you put the dotfiles? $HOME? XDG defines an cleaner hierarchy.

bheadmaster··on The cost of Go's panic and recover
I like to use Go error handling for providing curated error messages for each possible point of failure.

Stack traces in other languages do this in a way, but are often unreadable and require manually inspecting each function in the trace to figure out the reason of the bug. Even worse if some function in the middle catches the original exception and returns another exception, completely devoid of the former's context and information.

Even worse if you're using any kind of framework that renders stack traces useless ala async Rust or Java Spring. All you get is a bunch of noise from framework and almost nothing from your program.

In Go, most of the errors I get are chains of carefully written messages, e.g. "request failed: write file: create: directory does not exist". And given that errors are just values and not tied to a stack, they can internally be passed through channels in all kinds of complex goroutine pipelines, and not lose any information.

Go basically makes your life worse, until you get used to writing meaningful context-relevant messages and thinking about errors. Which in turn makes your life a lot easier when diagnozing and debugging an issue.

bheadmaster··on The number line freaks me out (2016)
True, but what I'm pointing out is - imagine parabolas never predicted movement of anything, or imagine that math itself never had any prediction power in the real world. The self-consistency and the aestethics and the ability to prove statement inside itself would all be just a bunch of symbolic games, much like poetry or crossword puzzles.

You may argue that that, in itself, is powerful, in which case fair enough. But that "power" would be comparable to that of poetry or painting, which, in my opinion, does a disservice to the true power that mathematics holds. Mathematics is much more powerful than poetry and painting, because poetry never helped us build nuclear reactors.

bheadmaster··on The number line freaks me out (2016)
> Rather, math's power stems from the fact that it emphatically does not expect or require the symbols to have any connection to real world observations.

What exactly do you mean by "power" here, if not the ability to predict real-world phenomena? In absence of it, what exactly would make it anything more than an exotic artform?

bheadmaster··on Framework's first desktop is a strange–but unique–mini ITX gaming PC
I didn't say it's not understandable, just that it breaks down - i.e. doesn't apply anymore.

The point of an analogy is to point out how our intuition tells us it's the same boat, despite having no parts in common with the initial boat.

As other comment mentioned, if you keep the sails and rebuild a new boat around it, no person in their right mind would feel that it's the same boat. It's very clearly a new boat, and the analogy breaks down.

bheadmaster··on Framework's first desktop is a strange–but unique–mini ITX gaming PC
The difference is that The Ship of Theseus had all its parts replaced one by one, in a long period of time. If you replace 90% of the ship at the same time (RAM, CPU and Motherboard), then the analogy breaks down.
bheadmaster··on The number line freaks me out (2016)
> math is ultimately about symbols. [...] Neither! It means that the string of symbols '2 = 2' is reducible to the symbol 'true', given certain axiomatic symbolic transformations. Nothing more, nothing less!

If that were true, math would be useless, and nothing more than an esoteric artform.

The true power of math comes from the correspondence between those symbolic transformations and observation from the real world. Two objects that look alike can be placed in juxtaposition with any other (different) two objects that look alike, and no matter how much we move them around, as long as we don't add or remove any objects, they can still be placed in the same juxtaposition as before (while this description may seem verbose and clumsy, in the real world it does not need a description - it is a much more primitive sensory perception, learned at an early age).

> obviously we can project concepts onto the symbols, like "integer" and "real number", and talk usefully about them, but those are the map and the symbols are the terrain

It wouldn't be "obvious" that we can project concepts onto symbols, if we didn't discover that symbols correspond to concepts and that symbolic transformations can help us predict the future. Thus I'd say it's the other way around: symbols are the map that we know how to read - of the terrain that we can't traverse easily.

bheadmaster··on Go-msquic: A new QUIC/HTTP3 library for Go
To be fair, the first line in the README.md says

    go-msquic is a Go wrapper for the Microsoft's QUIC library
So it's only the HN headline that is (technically) wrong.
bheadmaster··on An Infinitely Large Napkin [pdf] (2019)
No. Nuh-uh. Not me. I'll definitely find some time to read and work through this. As soon as I finish a few of these things I still have on my TODO list... Just a few more days...
bheadmaster··on Context should go away for Go 2 (2017)
> It’s not my job to provide you with alternative code. That’s your job.

It is not your job to tell me "that is wrong", yet you do it because it's easy. Suggesting an alternative (not necessarily providing the code) is less easy, so you don't wanna do it. That's fine. I just want you to be aware that the former without the latter is pretty much useless.

bheadmaster··on Context should go away for Go 2 (2017)
> It’s best not to acquire a mutex and launch a goroutine to read 3 bytes of data at a time.

io.Copy uses 32KB buffers. Other parts of standard library do too. If you're using Read() to read 3 bytes of data at a time, mutex is the least of your worries.

Since you seem to be ignoring sarcasm of my previous comment - just saying "don't do that" without suggesting an alternative way in the particular code context you're referring to, isn't useful at all. It's just annoying.

bheadmaster··on Context should go away for Go 2 (2017)
Thank you for your helpful input.
bheadmaster··on Kronotop: Redis-compatible, transactional document store backed by FoundationDB
> Java is the most performant runtime outside of C/C++/Rust.

Add Go to that list. Or any popular compiled language for that matter.

bheadmaster··on Context should go away for Go 2 (2017)
What would you suggest as an alternative?
bheadmaster··on Context should go away for Go 2 (2017)
Yes, but this is just proof of concept. For any given case, you can optimize your approach to your needs. E.g. single goroutine ReadCloser:

    type ioContextReadCloser struct {
        io.ReadCloser
        ctx context.Context

        ch chan *readReq
    }

    type readReq struct {
        p   []byte
        n   *int
        err *error
        m   sync.Mutex
    }

    func NewIoContextReadCloser(ctx context.Context, rc io.ReadCloser) *ioContextReadCloser {
        rcc := &ioContextReadCloser{
            ReadCloser: rc,
            ctx:        ctx,

            ch: make(chan *readReq),
        }
        go rcc.readLoop()
        return rcc
    }

    func (rcc *ioContextReadCloser) readLoop() {
        for {
            select {
            case <-rcc.ctx.Done():
                return
            case req := <-rcc.ch:
                *req.n, *req.err = rcc.ReadCloser.Read(req.p)
                if *req.err != nil {
                    req.m.Unlock()
                    return
                }
                req.m.Unlock()
            }
        }
    }

    func (rcc *ioContextReadCloser) Read(p []byte) (n int, err error) {
        req := &readReq{p: p, n: &n, err: &err}
        req.m.Lock() // use plain mutex as signalling for efficiency
        select {
        case <-rcc.ctx.Done():
            return 0, rcc.ctx.Err()
        case rcc.ch <- req:
        }
        req.m.Lock() // wait for readLoop to unlock
        return n, err
    }
Again, this is not to say this is the right way, only that it is possible and does not require any shenanigans that e.g. Python needs when dealing with when mixing sync & async, or even different async libraries.
bheadmaster··on Context should go away for Go 2 (2017)
True. But this code is only proof-of-concept of how non-context-aware functions can be wrapped in a context. Such usage of context is not standard.
bheadmaster··on Context should go away for Go 2 (2017)
There are two solutions, depending on your real use case:

1) You're calling Read() directly and don't need to use functions that strictly accept io.Reader - then just implement ReadContext:

    func (rc ioContextReader) ReadContext(ctx context.Context, p []byte) (n int, err error) {
        done := make(chan struct{})
        go func() {
            n, err = rc.Reader.Read(p)
            close(done)
        }()

        select {
        case <-ctx.Done():
            return 0, ctx.Err()
        case <-done:
            return n, err
        }
    }
Otherwise, just wrap the ioContextReader with another ioContextReader:

    reader = ioContextReader(ctx, r)
bheadmaster··on Context should go away for Go 2 (2017)
Contexts in Go are generally used for convenience in request cancellation, but they're not required, and they're not the only way to do it. Under the hood, a context is just a channel that's closed on cancellation. The way it was done before contexts was pretty much the same:

    func CancellableOp(done chan error /* , args... */) {
        for {
            // ...

            // cancellable code:
            select {
                case <-something:
                    // ...
                case err := <-done:
                    // log error or whatever
            }
        }
    }
Some compare context "virus" to async virus in languages that bolt-on async runtime on top of sync syntax - but the main difference is you can compose context-aware code with context-oblivious code (by passing context.Background()), and vice versa with no problems. E.g. here's a context-aware wrapper for the standard `io.Reader` that is completely compatible with `io.Reader`:

    type ioContextReader struct {
        io.Reader
        ctx context.Context
    }

    func (rc ioContextReader) Read(p []byte) (n int, err error) {
        done := make(chan struct{})
        go func() {
            n, err = rc.Reader.Read(p)
            close(done)
        }()

        select {
        case <-rc.ctx.Done():
            return 0, rc.ctx.Err()
        case <-done:
            return n, err
        }
    }

    func main() {
        ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
        defer cancel()

        rc := ioContextReader{Reader: os.Stdin, ctx: ctx}

        // we can use rc in io.Copy as it is an io.Reader
        _, err := io.Copy(os.Stdout, rc)
        if err != nil {
            log.Println(err)
        }
    }
For io.ReadCloser, we could call `Close()` method when context exits, or even better, with `context.AfterFunc(ctx, rc.Close)`.

Contexts definitely have flaws - verbosity being the one I hate the most - but having them behave as ordinary values, just like errors, makes context-aware code more understandable and flexible.

And just like errors, having cancellation done automatically makes code more prone to errors. When you don't put "on-cancel" code, your code gets cancelled but doesn't clean up after itself. When you don't select on `ctx.Done()` your code doesn't get cancelled at all, making the bug more obvious.

bheadmaster··on A secure distributed actor language
> People are free to target whoever they want when publishing on the internet.

People are also free to criticize whatever is published on the internet. Hypotetically not being a part of the "target audience" doesn't preclude one form such freedom.

I agree with the comment above: the introduction doesn't really "introduce" the reader to the language, it only introduces the reader to the syntactic constructs used in the language. Such introduction would better fit in the "specification" section.

bheadmaster··on Stimulation Clicker
I had a great run and accidentally reloaded my page :(

Feature request: save current state in local storage so I can resume when I open it back again.

bheadmaster··on Go Protobuf: The New Opaque API
Buf CLI itself is licensed under a permissive Apache 2.0 License [0]. Since Buf is a compiler, its output cannot be copyrighted (similar to proprietary or GPL licensed compilers). DISCLAIMER: I am not a lawyer.

Buf distinguishes a few types of plugins: the most important being local and remote. Local plugins are executables installed on your own machine, and Buf places no restrictions on use of those. Remote plugins are hosted on BSR (Buf Schema Registry) servers [1], which are rate limited. All remote plugins are also available as local plugins if you install them.

It's worth to mention that the only time I've personally hit the rate limits of remote plugins is when I misconfigured makefile dependencies to run buf on every change of my code, instead of every change of proto definitions. So, for most development purposes, even remote plugins should be fine.

Additionally, BSR also offers hosting of user proto schemas and plugins, and this is where pricing comes in [2].

[0] https://github.com/bufbuild/buf/blob/main/LICENSE

[1] https://buf.build/blog/remote-plugin-execution

[2] https://buf.build/pricing

bheadmaster··on Procman: Simple gRPC single-process manager
My coworker had a scenario where he needed to stop the execution of a service (inside container) from another service (inside another container) temporarily. All the methods of doing that required having access to Docker daemon socket and root/docker group.

I wrote this tool that could be used as a docker entrypoint, would start the specified process, and exposed Start/Stop/Restart controls via gRPC.

← PreviousPage 8 of 34Next →