upvote
That seems to be a pretty consistent quality level for the entire library. Look at the implementations in sp_math, yikes.
reply
Oh man. Oof. I'm sure there must be some repository out there that has an AGENTS.md but isn't pure slopcode, but I haven't seen it yet. The number of people who can be trusted to vibe code "responsibly" is probably about the same as the number of people who can be trusted to write memory safe C.
reply
As noted in my other comment though, some interesting decisions and interfaces do point to some degree of human intervention. I have recently written a similarly sized WebAssembly runner in C using agents (feel free to review: [1]) so I'm pretty certain that agents simply don't do that kind of things themselves...

[1] https://github.com/lifthrasiir/wah/

reply
> feel free to review: [1]

feel free to pay me before asking me to review slop

reply
Feel free to ignore if you don't feel so.
reply
sp_math.h is, as noted at the top of the file, a repackaging of https://github.com/HandmadeMath/HandmadeMath

It is not part of the core library. It is certainly not meant as a reference-level implementation of math functions. It's there so you can write an easing function for a game without pulling in libc. It seems like its existence has offended you. If that's the case...I'm sorry? At every possible point, I note as loudly as possible exactly what that library is. I found your tone extremely dismissive and disrespectful and I don't care to engage with that any more than I already have.

reply
> It is not part of the core library. It is certainly not meant as a reference-level implementation of math functions. It's there so you can write an easing function for a game without pulling in libc.

I saw the note and ignored it because it's not actually a repackaging of HHM. It simply happens to define a few vaguely similar functions. It doesn't reuse the naming conventions (MulVec3f vs vec3_scale), it doesn't reuse the interface (see SP_MATH_IMPLEMENTATION), and it's missing genuinely useful bits like the matrix functions.

Moreover, the quality of what's been added is significantly worse. Look at sp_sys_expf:

    f32 sp_sys_expf(f32 x) {
      f32 result = 1.0f;
      f32 term = 1.0f;
      for (int i = 0; i < 20; i++) {
        term *= x / (f32)(i + 1);
        result += term;
      }
      return result;
    }
I can't imagine a good reason why anyone (even an LLM) would ever write a 20th order taylor series for expf. A single FMA can improve on this and have capped relative error to boot, and that's not even a good way to do it. See what happens with your function at +-10 for comparison. At the f32 limit of 88, you achieve an honestly impressive 100% relative error.

Also, because sp_math doesn't use FMAs, your library isn't reproducible. Different compilers will produce different values. Reproducibility is a pretty nice property in games.

reply
I don't like that slopcode angle either, but unfortunately I have to say that you do have picked a wrong library to bundle. For example, it's almost likely that there is a correct (not just accurate enough, but correct) implementation of sqrt in your CPU because IEEE 754 mandates that. Unless you're doing softfloat you simply want to wire it via asm.
reply
"How bad can it be, I mean I know that numerics are not many people's strong suit, but..."

... ... ... oh wow, the math functions are really bad implementations. The range reduction on the sin/cos functions are yikes-level. Like the wrong input gives you an infinite loop level of yikes.

reply
Here’s a diagram that very visibly shows the error: <https://www.wolframalpha.com/input?i=plot+y+%3D+sin%28x%29%2...>. And that’s even without accumulated float error if you start outside the range [−π, π] (huge numbers will just be wildly wrong).
reply
> That seems to be a pretty consistent quality level for the entire library. Look at the implementations in sp_math, yikes.

That does spin the meaning of "Sp.h is the standard library that C deserves"

reply
The point of the library is that you do not call the low level allocation primitive to allocate a single string. Of course, in simple programs which exit immediately, there is no difference between using a page allocator and a heap allocator. In real programs, I use an appropriate allocator for the allocation rather than making arbitrary calls to malloc(). In the sp.h examples, I use the page allocator to keep freestanding Linux simple. I could swap out a single line to be backed by an arena, but it misses the forest for the trees.

sp_log() writes directly to an IO writer. An IO writer can be buffered or unbuffered, but is unbuffered by default. This is a feature, not a bug. Have a look through the IO code!

Cheers and thanks for reading.

reply
So every program using sp has to re-invent malloc or multiple copies of their own bespoke allocator and this is supposed to be a good idea?
reply
The library provides a few basic allocators.
reply
q> sp_log() writes directly to an IO writer. An IO writer can be buffered or unbuffered, but is unbuffered by default. This is a feature, not a bug. Have a look through the IO code!

Why is the unbuffered default? Is there any thoughts on this?

reply
A buffered file may not be fully written to disk if the program exits suddenly. That’s generally a highly undesirable trait for a log file.
reply
Line buffering solves this
reply
Not just the TLB, but the L1 D$ will be very unhappy as well. All heap objects being page aligned on most microarchs ends up making every object start at cache set 0 because the set determination ends up being indexed off of the offest within a page so that the TLB lookup can happen in parallel with the set load.
reply
Jesus! Claude could've told this guy all these things. People underestimate how much the average malloc implementation does and how many considerations it makes. Or how much IO sucks.
reply
> Jesus! Claude could've told this guy all these things.

Claude probably wrote it.

reply