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
x-post from the epstein thread

i wonder how it ended up there

Idk, but there are other like nvidia-smi,
He might have been into programing, Who knows. He definitely was somewhat tech savvy given he understood 4chan.
He fell for it and tried installing gentoo.
 
I believe I am at that point where an LLM can no longer help me other than menial tasks. I tried working on this on a branch but I have fucked up the organization.
I'm not an LLM evangelist and acknowledge it has limitations, but Claude AI can 100% handle more than 5 small Go files, and you can link it to the GitHub repo so it always up to date and has context of what's committed. I know this because I've been trying it out while learning Godot with C# and its managing around a couple dozen C# source files, as well as Godot scene files (so still a small project, used about 20% of the free tier for coverage, but bigger than your project). Its still able to introduce features, bugfix, refactor, analyse architecture etc at this size. You still need to validate its changes yourself and make sure you understand what its outputting, obviously.
I haven't used Claude Code either, which you use in your terminal or as VSC/Rider extension. I have used Github Copilot and that also has a larger context window than a disconnected ChatGPT chat that is isolated away from the codebase.
 
but Claude AI can 100% handle more than 5 small Go files, and you can link it to the GitHub repo so it always up to date and has context of what's committed.
I didn't know this could be done, That sounds great as I have been using Claude!
Issue is I have a problem that isn't on Discord's API or anywhere else on the internet. I am trying to get the private dms but the only place where that is done is the Discord chat exporter. I do not think the LLM has the necessary training data to make a function to do this, let alone other problems similar to this.
I also want to make it so that it watches a server as some of the lolcows I am watching DFE their servers every month or show up across multiple different servers. I dunno how I'll have Discord send my server the messages.
Then again I can have the LLM do menial tasks, like having it set up all the api request functions or basic database functions.
Fortunately, there's a great resource for this: https://go.dev/doc/modules/layout
I guess I'll organize once this gets too big, I will keep in mind the organization structures.

I have checked out some of your repositories and I think they're very interesting.
 
I didn't know this could be done, That sounds great as I have been using Claude!
Issue is I have a problem that isn't on Discord's API or anywhere else on the internet. I am trying to get the private dms but the only place where that is done is the Discord chat exporter. I do not think the LLM has the necessary training data to make a function to do this, let alone other problems similar to this.
I also want to make it so that it watches a server as some of the lolcows I am watching DFE their servers every month or show up across multiple different servers. I dunno how I'll have Discord send my server the messages.
Then again I can have the LLM do menial tasks, like having it set up all the api request functions or basic database functions.

I guess I'll organize once this gets too big, I will keep in mind the organization structures.

I have checked out some of your repositories and I think they're very interesting.

Since iirc you're just getting into Go programming, I highly suggest reading this article: https://go.dev/blog/pipelines, and especially the section "Explicit cancellation". Painless async and channels are a big part of what makes Go such a special language. I hope I can get you started thinking about asyncing from early on and how amazingly easy and powerful Go makes it.

While there is all sorts of amazing info in the article, I want to emphasize the power of channels and specifically chan struct{}. Note that struct{} here is just an empty object (like setting a var to {} in JS). In the stdlib source, you can see the immensely important context.Done() just returns a simple read-only channel. The "Done" signal happens when that channel eventually closes.

You see, the beauty of all this is you can't write to a closed channel, but you can read from one all you want—reading from a closed channel returns the default initialized (zeroed) equivalent of whatever type the channel is for. Note that you can't close an already closed channel.

Here's a recent (not merged) example of how I use this concept to eliminate a rare data race involving user data in my chat client:
C-like:
type clientUser struct {
    ID       uint32
    Username string
    found    chan struct{}
}

func newClientUser(id uint32) clientUser {
    return clientUser{
        ID:    id,
        found: make(chan struct{}),
    }
}

type userTable struct {
    sync.Map
    Client clientUser
}

// TODO: Make this value passing less retarded.
func NewUserTable(clientID uint32) *userTable {
    return &userTable{
        Client: newClientUser(clientID),
    }
}

func (ut *userTable) ClientName() string {
    select {
    case <-ut.Client.found:
        return ut.Client.Username
    default:
        return ""
    }
}

func (ut *userTable) AddUser(u *User) *User {
    select {
    case <-ut.Client.found:
    default:
        if ut.Client.ID == u.ID {
            ut.Client.Username = u.Username
            close(ut.Client.found)
        }
    }

    // ...

    return u
}
The structure of this code isn't ideal and types aren't organized sensibly, as it's part of a very old codebase that was made when I knew way less about Go, and I'm duct taping over stuff until concord (private repo, as of writing) is ready. So it's not a model for all good practices, but there's something to learn here.

I needed an easy way to identify the username of the person running the client. The easiest method, given username changes and unicode bullshit, was our constant numerical user IDs (mine is #160024). You set your user ID in the config file, and the program will figure out your username from incoming user data by matching based on author ID. Multiple threads/routines need to check for this username value (e.g. for reply notifications and highlighting), so simply checking if ut.Client.Username is an empty string across multiple threads/routines is a textbook data race—one that simply didn't matter enough for me to fix for a while due to time constraints lol.

There are 3 (practical) ways to fix this problem:
  1. Have a routine sitting in the background, blocking until a request comes in (via a channel) for the username string, and then sending it back when needed. (Not ideal).
  2. Something with a mutex (Overkill and a PITA).
  3. Make clever use of select statements and a "Done"/"Found" channel that acts sorta like a valve. While ut.Client.Username is empty, the ut.Client.found channel remains open; once found, the channel is closed. This acts as a thread-safe flag that helps us return this shared string safely. (Foolproof and relatively concise).

    The default blocks in the select statements only trigger when the other channel(s) read from above are empty and there's nothing to receive. Closing the ut.Client.found channel causes it to send out an empty struct every time it's read from, so the defaults no longer get reached. This way, we truly turn select into a whole new type of switch.
I later found out there's an even easier way to get the right username that requires none of this, but that's for another poost :story:

Edit: for closing channels, you may find sync.OnceFunc helpful. It's great for defer cleanup functions.
 
Last edited:
Stop using AI, it's bad for your brain.
It's only bad if you use it as a crutch, but for spitballing/prototyping it's great. Especially when you are experienced enough to go over the generated code, input commentary so it's documented for future browsing and appropriate it. Basically, if you are a senior dev (as a reference) it can be used like a team of junior devs without the hassle of herding cats.

To resume, just don't be a retard and use it for it's intended use, not as a slave. But yes it's bad for your brain if you use it like the majority of people.
 
It's only bad if you use it as a crutch, but for spitballing/prototyping it's great. Especially when you are experienced enough to go over the generated code, input commentary so it's documented for future browsing and appropriate it. Basically, if you are a senior dev (as a reference) it can be used like a team of junior devs without the hassle of herding cats.

To resume, just don't be a retard and use it for it's intended use, not as a slave. But yes it's bad for your brain if you use it like the majority of people.
I learn best by doing and experimenting though
 
I absolutely understand, it's the most basic and reliable way of learning. Learning theory, trying and then self-correcting is basically what the brain do too.
I firmly believe that the mechanical act of programming itself is vital for doing it correctly, you have more time to think about what you're doing as you do so
 
Stop using AI, it's bad for your brain.
It's only bad if you use it as a crutch, but for spitballing/prototyping it's great.
No, this is cope. Not the "it's great" part, that's true of course, but the "it's only bad if" part. Just like with other great and society-transforming inventions like automobiles and personal mobility vehicles, the "if" part always happens. Except this time it isn't just going to turn everybody fat and gross, but cause a severe cognitive decline that already can be measured in the late Z generation.

Obviously, feel free to go ahead and keep pumping out and consuming AI slop, this genie isn't ever going back in the bottle. But let's not kid ourselves about the writing on the wall here.
 
I always feel like an idiot entering this thread, because everyone is talking about these computer science concepts I can't follow along. Regardless, I'm happy I made the Sieve of Eratosthenes in Lisp! Or at least close to the solution. I'm still pleased with myself.
Code:
(defun find-primes(end)
  "Purpose is to find the primes with a given number"
  (let ((numbers (make-array (+ 1 end) :initial-element t)))
    ;;set 0 and 1 to nil
    (setf (aref numbers 0) nil)
    (setf (aref numbers 1) nil)
    
    ;;now for the loops
    (loop for p from 2 to end
      do (if(and (eql (aref numbers p) t)(<= (expt p 2) (length numbers)))
        ;;another loop
        ;;this time create a local variable
        (let ((r (expt p 2)))
          (loop for r from r by p to end
            do(setf (aref numbers r) nil)
          ))))
        ;;now print the final results
        (dotimes (i end)
          (if (eql (aref numbers i) t)
          (format t "~d " i)
          ))))
Feel free to comment and critique!
 
I always feel like an idiot entering this thread,
same tbqh, i participate only when the discussion is normie enough for me to be able chip in to the conversation
Regardless, I'm happy I made the Sieve of Eratosthenes in Lisp! Or at least close to the solution. I'm still pleased with myself.
hey man thats great! for hobby programming the most important thing is to have fun (while still learning something along the way)
 
I always feel like an idiot entering this thread, because everyone is talking about these computer science concepts I can't follow along. Regardless, I'm happy I made the Sieve of Eratosthenes in Lisp! Or at least close to the solution. I'm still pleased with myself.
Code:
(defun find-primes(end)
  "Purpose is to find the primes with a given number"
  (let ((numbers (make-array (+ 1 end) :initial-element t)))
    ;;set 0 and 1 to nil
    (setf (aref numbers 0) nil)
    (setf (aref numbers 1) nil)
   
    ;;now for the loops
    (loop for p from 2 to end
      do (if(and (eql (aref numbers p) t)(<= (expt p 2) (length numbers)))
        ;;another loop
        ;;this time create a local variable
        (let ((r (expt p 2)))
          (loop for r from r by p to end
            do(setf (aref numbers r) nil)
          ))))
        ;;now print the final results
        (dotimes (i end)
          (if (eql (aref numbers i) t)
          (format t "~d " i)
          ))))
Feel free to comment and critique!
The coolest prime sieve I ever saw was the concurrent prime sieve of Tony Hoare, as presented by Rob Pike in his talk about concurrency patterns. Link to a github I found with the talk and the code examples he used. Yours is interesting and probably more efficient in some ways.
Monads are just coroutines btw. They’re both functions whose execution continues after they return a value.
 
Can you elaborate? I don't see it.
“Calling a coroutine” is equivalent to yielding into the coroutines execution context and a coroutine “returning a value” is equivalent to it communicating a value to the calling process. In this model, the only difference between a subroutine (function) and a coroutine is that a subroutine’s execution context ends when it returns a value, while a coroutine’s context continues to exist.
In this way, a monad is like a coroutine because when you call into a monad, you pick up whatever state is guarded by the monad from the last time it was called and augment it for the next time the monad is called.
Closures are also coroutines and thus also monads btw.

Edit:
There is a second difference between coroutines and subroutines I forgor about which also applies between coroutines, monads and closures (most of the time, I think), that is subroutines have a strictly linear hand off of control (A calls B which returns to A which then calls C, etc.) while coroutines hand off control in a non-linear fashion (A calls B which calls C which returns to A). Closures and monads usually behave like subroutines in this way.
 
Last edited:
i am totally ignorant on coroutines
can someone explain to me why i would want to use coroutines instead of just spawning and managing worker threads myself the regular way and handing them whatever task i want done concurrently in the form of some 'task' or 'executable' object?
 
Back
Top Bottom