HackerTrans
TopNewTrendsCommentsPastAskShowJobs

OskarS

no profile record

comments

OskarS
·18 gün önce·discuss
One useful thing to do sometimes when looking at whether or not a user is interested in participating in Wikipedia or just participating in arguing about things is to look at their contributions to actual wikipedia articles, the thing Wikipedia is all about.

This is the list of articles Sanger contributed to in 2026: [1]

Compare that too all his contributions: [2]

Does it seem like this person is participating in Wikipedia in a genuine way? Or is he there to start political arguments on various internal pages?

[1]: https://en.wikipedia.org/w/index.php?title=Special%3AContrib...

[2]: https://en.wikipedia.org/w/index.php?title=Special%3AContrib...
OskarS
·25 gün önce·discuss
They can certainly be part of the standard library, it's just that you have to make the programmer be specific: it's a bad idea `new Random(seed)`, because you can then never update the `Random` class, and you might get stuck with a terrible default forever. But having a `new Xoshiro256(seed)` is a fine thing to have in your standard lib, given that quality PRNGs are such a common need.
OskarS
·25 gün önce·discuss
I've always thought that random number generators are one of the best examples of Hyrum's law ("all observable behaviours are part of your API"): once you release a random number generators that either uses a default seed or allows you to seed it, you can't ever change it, it's a huge breach of backwards compatibility. Imagine if you did a Minecraft style game that relied on the behaviour of some PRNG, and then you changed the implementation? The entire game will break. That's why GNU libc still uses a terrible LCG for rand() despite the fact that much better generators exist: they can't ever fix it, because srand() exists and people rely on it.

On the other hand, it's STUPENDOUSLY useful to have "default" random functionality in your core library, for the "just give me a random number" or "shuffle this array, I don't care how" users, who don't really care about the details. But if you do that: always seed it with some external entropy (current time or /dev/random or whatever), don't even allow users to seed it. That means you can improve it in the future, because users already can't ever rely on the sequence. If the users do want to rely on the sequence, they should have to specify the exact engine they want.

TL;DR: System.Random in C# should not ever have been seedable, big mistake.
OskarS
·29 gün önce·discuss
Everyone knows about bit-fiddling functions, what the poster was referring to is using this trick to not have to store the capacity for a dynamic vector. Which is genuinely very clever and rare, I don’t think I’ve ever seen it done quite like this either. I think that’s probably because it’s not really that good of an idea, if the vector can shrink, you really should store the capacity.
OskarS
·29 gün önce·discuss
It doesn’t really work though for generic vectors. If you support not just vec_push but vec_pop as well, then you really do need to store capacity separately or else call realloc way more often than you normally need to.
OskarS
·geçen ay·discuss
As a non-web dev, I have a question about this part:

> There was a sad coda; as is the way of contract work, I moved on. I explained what I had built to my replacement, that it always worked even without javascript. He was appalled and said, “but that’s a lot more work for us.”

Why is it more work? The approach described in the article seems honestly reasonably simple: just write the standard <input> components for the form, have a submit button at the bottom. When I was making my own websites many years ago now, that's how it worked, and it wasn't that hard. Maybe it's reflecting my ignorance in this field, but doing fancy front-ends seems much harder to me.
OskarS
·geçen ay·discuss
Not even young people: I have a very expensive MacBook Pro M5 i got from work, but my personal laptop is old and needs replacing. I’m a well-paid senior software developer and could afford any computer I wanted. But the MacBook Neo is a top contender even for me. I mostly need something for like editing documents, hobby coding and watching YouTube videos. It runs Codex or Gemini-CLI fine. For the price point, it seems perfect for a second computer. I could pay premium prices for something better, but honestly: I don’t think I need to.
OskarS
·geçen ay·discuss
Sure! The main formats are VST3 (from Steinberg, the most popular format), AU (from Apple, supported by most macOS hosts, and Logic only uses AU), AAX (for Avid Pro Tools) and CLAP (an open source variant, that's the best of all of them but is having trouble getting market share). Then there is also "Standalone", which is when you just run your plugin as a standalone app.

Because of this plethora of standards, most plugin developers (including us, I work at XLN Audio) use the JUCE C++ framework, which provides a uniform interface to all these formats and more. It's available on GitHub under a GPL license if you just want to play with it (it has excellent tutorials and example projects). If you're just curious about development thing, I recommend using Reaper as a host to test in, both because it's essentially free (it's free like WinRAR is free), and it has tons of options for how to run plugins (all in the main process, all in a bridged process, every plugin in a dedicated process, etc.).

Audio plugins are essentially dynamic libraries loaded at runtime, and a common way to run them (used to be universal, but some hosts are changing) is that the dynamic library is just loaded in the main process address space and the host communicates with it by calling functions on it. That means that if a single plugin (out of maybe dozens in a project) crashes, it takes the entire host down. In addition, if you have multiple instances of the same plugin (very common, you might have the same effect on multiple tracks, for instance), all global and thread_local variables are shared between them, which makes global variables a total nightmare, and raises the thread_local problem I mentioned earlier.

Our products use JUCE for the unified interface, but then we have an entirely custom Lua codebase for the GUIs and scripting the products themselves (with lots of connections to the audio engine, which is of course C++). There are very limited languages you can embed this way, because of the requirements I mentioned above. The ones I've looked at which you could possibly do it with is Lua, Python (3.12+), JavaScript and Tcl. I haven't done a lot of testing outside of Lua though, this is just me looking at the embedding APIs. You could also do it with web views, and recent versions of JUCE provides nice ways to do that.

I wouldn't do it with Janet if it uses thread local state this way, but maybe it works. It would definitely work if you spun up dedicated threads for each instance and communicated the events back and forth, but that seems like a bad idea.

Let me know if you have more questions, this is a very weird field of programming that most developers are not exposed to.
OskarS
·geçen ay·discuss
That’s a really great explanation, I think I more or less followed all of it. Thanks for taking the time to write it out!
OskarS
·geçen ay·discuss
The UI for audio plugins generally work in an event driven manner: you get events like mouseMove, keyDown, repaint, etc. from your host. In response to those events, you run your script to figure out what you need to do. You have no control over which thread calls these things, it can be the GUI thread that runs all of them, it can be run on background threads in parallel, etc. Different hosts do it differently. If Janet using thread-local state, this just doesn't work: the state for one instance is completely different from another, and there's even no guarantee they're running the same scripts.

Consider the most famous embedded language, JavaScript in browsers: you can have any number of tabs open at the same time, and if the JavaScript interpreters for each of those used a bunch of thread-local storage, it would place huge restrictions on how the browsers could schedule and parallelize the callbacks for the JavaScript in those tabs.

The only way I can see this working is if you spin up a thread for each instance, and when these events come in, you wake up those threads, send over the event information, block until the interpreter thread finishes. But that's both inefficient and a real architectural hassle.

All I want is an object that's like `janet_interpreter *interpreter = janet_make_interpreter();` and then you pass that to the functions instead of doing all these magic things with global variables and thread local state. That's it.
OskarS
·geçen ay·discuss
So you can't execute a Janet script on a different thread than it was created on? Still not good: if you're making audio plugins, you don't control the threads which your program runs on. It's just not good enough, IMHO.
OskarS
·geçen ay·discuss
My first question too, and I checked out the linked book [1], and sure seems like it! There's global functions like `janet_init()` and `janet_loop()` all over the place.

A language shouldn't advertise itself as "embeddable" if it does this. It means you can't have multiple interpreters, you can't use it on multiple threads, etc. GNU Guile does this too, and it's a baffling decision! For my field (audio plugins like VSTs), it means it's absolutely a no-go, because hosts can load any number of instances of your plugins and potentially run them in parallel in the same address space, they can't rely on global state like this. Each interpreter has to be separate.

Lua does this right, as does Python (as of 3.12, when they made the GIL local to each interpreter) and I think most of the JavaScript engines. And it's not hard, instead of a global `janet_init()`, just have an opaque pointer bundle all the state, like `janet_init(interpreter)`. If you want a global interpreter, just stick it in a global variable.

[1]: https://janet.guide/embedding-janet/
OskarS
·geçen ay·discuss
> and with short selling in public markets being possible, an accurate price will be established very quickly.

I know very little about markets, but: aren't the short-sellers just going to provide liquidity for the big index funds? Like, if the funds HAVE to buy SpaceX, and the funds are enormous, wont every single stock sold short be immediately gobbled up, as well as pretty much anyone else wanting to sell? Even if everyone else is selling like mad, it wont affect price much at all?

Maybe this is naive, but if these enormous funds are more or less forced to buy SpaceX, it seems impossible that "actual price discovery" is going to happen in any reasonable amount of time, and the short-sellers will be screwed.
OskarS
·geçen ay·discuss
I would guess that the 1998 era Microsoft compiler didn't have nearly as many warnings as modern compilers do.
OskarS
·2 ay önce·discuss
That is how I (a non-lawyer) understand it as well, but I wonder if it's so simple when you combine it with the GPLness of it all. Like, releasing something under the (A)GPL is a license to use and modify the code how you see fit, and that goes "virally" through the forks. This fork is just using their own GPL-licensed code, and it seems unreasonable (for some definition of "unreasonable") to limit forks in this way. I think it's plausible you can make an argument that if you make this kind of restriction in your GPL codebase, you're violating the GPL license of the original ("upstream") authors.
OskarS
·4 ay önce·discuss
Certainly that’s part of it, but also just NIMBYism. Los Angeles were able to defeat the Owen’s Valley farmers back then, I don’t think they would be now.
OskarS
·4 ay önce·discuss
Yeah, the "two-bit saturating counter" thing is pretty much exactly how I thought it worked (which would be terrible for the example in the article), but I had no idea about the fact that it also kept track of the branch history thing, and how that maps to different branch predictor entries. Thanks for the link, that's really fascinating!
OskarS
·4 ay önce·discuss
Hmm, that's interesting. The code as written only has one branch, the if statement (well, two, the while loop exit clause as well). My mental model of the branch predictor was that for each branch, the CPU maintained some internal state like "probably taken/not taken" or "indeterminate", and it "learned" by executing the branch many times.

But that's clearly not right, because apparently the specific data it's branching off matters too? Like, "test memory location X, and branch at location Y", and it remembers both the specific memory location and which specific branch branches off of it? That's really impressive, I didn't think branch predictors worked like that.

Or does it learn the exact pattern? "After the pattern ...0101101011000 (each 0/1 representing the branch not taken/taken), it's probably 1 next time"?
OskarS
·4 ay önce·discuss
> Two boxes is the only choice that makes sense. It is always better than one box.

Congratulations on your $1,000. I'll use some of my $1,000,000 I got by nonsensically picking one box to toast in your honor and dedication to logic.
OskarS
·4 ay önce·discuss
Conceptually it's quite similar to how C++ templates work (not including C++20 concepts, which is the kind of constraining you're talking about).

I quite like it when writing C++ code. Makes it dead easy to write code like `min` that works for any type in a generic way. It is, however, arguably the main culprit behind C++s terrible compiler-errors, because you'll have standard library functions which have like a stack of fifteen generic calls, and it fails really deeply on some obscure inner thing which has some kind of type requirement, and it's really hard to trace back what you actually did wrong.

In my (quite limited) experience, Zig largely avoids this by having a MUCH simpler type system than C++, and the standard library written by a sane person. Zig seems "best of both worlds" in this regard.