Programming thread

  • Want to keep track of this thread?
    Accounts can bookmark posts, watch threads for updates, and jump back to where you stopped reading.
    Create account
The notion is to staple on bits of requirement/etc. to a goroutine. I don't get what you dislike about it.
Probably got a lot to do with my habit of overcomplicating stuff, yes. I had a problem with that in my ""discrete math" for CS majors" class years and years ago when it came to induction. Will read the needful later, thank you!
 
I found out about the context type in Golang the other day, and it rubs me the wrong way. I can't articulate why, haven't done enough reading on it yet, but it feels like a code smell. Basically you can use it to manage operations that go across API boundaries or processes (like killing a web request that requires a database transaction, if for some reason you need to do that upstream), but most of the time you're passing it around, you don't actually use it? Maybe someone who writes large scale Go programs can explain why it's a logical design choice and I'm wrong, if I'm wrong.
They’re essentially timers that can be passed into functions and shared between goroutines. The logic is pretty simple, if you have a single task that requires a series of function calls and/or multiple goroutines, but you also want to ensure that task finishes within a set period of time, you need a single timer that manages it all. Context also retains some functions to help clean up things if the request gets cancelled/times out.
 
You could even look at the implementation if you wanted to, IMO the CPython code base is pretty easy to read, but I'm also a crazy person.
It explicitly and intentionally is easy to read at the expense of optimizations that would stop CPython from being so abysmally slow.
 
I found out about the context type in Golang the other day, and it rubs me the wrong way. I can't articulate why, haven't done enough reading on it yet, but it feels like a code smell. Basically you can use it to manage operations that go across API boundaries or processes (like killing a web request that requires a database transaction, if for some reason you need to do that upstream), but most of the time you're passing it around, you don't actually use it? Maybe someone who writes large scale Go programs can explain why it's a logical design choice and I'm wrong, if I'm wrong.
The main purpose for it is to tell the goroutines/threads you spawn when to fuck off and stop running. Signaling when related processing is "Done".

From a library I wrote:
C-like:
// Brute force nonces until a valid solution is found.
func genHashes(ctx context.Context, c Challenge) <-chan Solution {
    var (
        out   = make(chan Solution, 1)
        sha   = sha256.New()
        nonce = rand.Uint32()
    )

    go func() {
        defer close(out)

        for {
            select {
            case <-ctx.Done():
                return
            default:
            }

            sha.Write(fmt.Append(nil, c.Salt, nonce))

            sol := Solution{
                Hash:  sha.Sum(nil),
                Nonce: nonce,
            }
            // Ensure we don't hang if out channel is full on ctx close.
            select {
            case <-ctx.Done():
                return
            case out <- sol:
            }

            // Reset hasher input for next iteration.
            sha.Reset()
            nonce++
        }
    }()

    return out
}

// Solve Challenge c. Returns Solution that can be submitted.
func Solve(ctx context.Context, c Challenge) (Solution, error) {
    duration, err := time.ParseDuration(fmt.Sprintf("%dm", c.Patience))
    if err != nil {
        // Fallback to common value.
        duration = 3 * time.Minute
    }

    ctx, cancel := context.WithTimeout(ctx, duration)
    defer cancel()

    sol := make(chan Solution, 1)

    go func() {
        // A reasonable hardware-based job limiter.
        // Use 1 worker per thread at most.
        threads := runtime.NumCPU()
        for i := 0; i < threads; i++ {
            go func() {
                hf := genHashes(ctx, c)
                // Loop until answer has been found.
                // Should break when hash worker terminates.
                for h := range hf {
                    if checkZeros(c.Diff, h.Hash) {
                        h.Salt = c.Salt
                        // Set host url to submit this to.
                        h.host = c.host
                        sol <- h
                    }
                }
            }()
        }
    }()

    select {
    case <-ctx.Done():
        return Solution{}, ctx.Err()
    case s := <-sol:
        return s, nil
    }
}

Multiple worker processes are spawned to generate hashes until a valid PoW solution is found. So we need a way to tell the workers when to stop; contexts work great for this. It also makes handling timeouts super easy.

Passing values through contexts, while possible in limited circumstances, is generally discouraged. If you find yourself needing to pass info that way, you should probably rethink your strategy.
 
Hearing this talk about lisp made me give it a shot. Way different from C. I have to ask, how do you keep track of all the parenthesizes? Also, I found out old Naughty Dog used a dialect of lisp called Game Oriented Assembly Lisp for their PS1 and PS2 games. Some mad lads have decided to “revive” it for homebrewing? Here’s the link. I think it’s neat plus it brings back a lot of memories. I can’t imagine the amount of work it took but I find it inspiring!
 
I have to ask, how do you keep track of all the parenthesizes?
Rainbow parens, line breaks, and an editor that can auto-align it for you.
1768429513344.png
Plus, the feature most editors have that highlights the matching brace when the cursor is over one.



Bonus: the match % motion for vim makes it really easy to navigate between matching sets of parens. Put your cursor over any opening paren, hit d% and it will cut the whole block, preserving any nesting over following lines. Insanely useful for quickly moving chunks of function calls. I set up my emacs evil-mode so that it maps TAB to match in normal mode for quick jumping.

1768483598423.png
From the link I provided above, capped for posterity.
 
Last edited:
Should rename this thread to language masturbation.
no dude you don't understand dude
this obscure lisp dialect that's only used by 7 dudes worldwide (they're all in my esolang discord btw) is totally the best thing ever
just look at the sick code i wrote in it:
Code:
l()g(a[kkk()])+=x()()[0x01](r4[rx(3)[0x02]])
bet your babylang can't do something this cool :smug:
 
Hearing this talk about lisp made me give it a shot. Way different from C. I have to ask, how do you keep track of all the parenthesizes? Also, I found out old Naughty Dog used a dialect of lisp called Game Oriented Assembly Lisp for their PS1 and PS2 games. Some mad lads have decided to “revive” it for homebrewing? Here’s the link. I think it’s neat plus it brings back a lot of memories. I can’t imagine the amount of work it took but I find it inspiring!
Yeah, in their early PS1 games they basically ignored the Sony approved tooling and libraries and hacked everything straight to the hardware.

Their original language was GOOL and it was a lisp that compiled to the native assembly for the PS1. They might've written their own assembler too, not sure about that.

Here's a great article Andy Gavin wrote about it.

Actually, the whole Making Crash Bandicoot series is a great read if you have the time. It covers the whole thing, from the technical issues, to the marketing and business issues too.
 
What does it do that copypasting into ChatGPT and using your noggin can't?
I don't know I am not a programmer. I am asking the wizards.
I have never used it, I just have gemini which came with a drive subscription used for business.
I use it basically exclusively for making shit-tier memes and because search engines suck now.
 
I use it basically exclusively for making shit-tier memes and because search engines suck now.
keep it that way
using AI for anything more involved than "generate a video of elon musk giving a blowjob to pepe the frog" is bad, it atrophies your mind and leads to cognitive decline the more you get habituated to using it
 
keep it that way
using AI for anything more involved than "generate a video of elon musk giving a blowjob to pepe the frog" is bad, it atrophies your mind and leads to cognitive decline the more you get habituated to using it
Oh I agree. I had to ask someone sane, because all of these retards on X keep saying that its going to somehow do everything for us, and that we're all going to be left behind by people who know how to ask for something.
 
keep it that way
using AI for anything more involved than "generate a video of elon musk giving a blowjob to pepe the frog" is bad, it atrophies your mind and leads to cognitive decline the more you get habituated to using it
as somone who has used it, the only thing AI is "useful" for is writing code comments/generic text/git messages, autofilling static data like enums, or generating extremely basic code like for loops. Any other use will either lead to uncompilable code or logic errors that will take time to track down.
 
Back
Top Bottom